package com.fingard.dsp.bank.directbank.fngrd01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.fingard.constant.DateFormat2;
import com.fingard.constant.Format;
import com.fingard.diagnostics.LogHelper;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.ReqOtherElse;
import com.fingard.dsp.bank.reqrespobj.otherelse.RetAtsOtherElse;
import com.fingard.text.StringHelper;
import com.fingard.text.XmlHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.SignatureException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class FnGrd01OtherElse extends FnGrd01Base implements IOtherElse {
    @Override
    public RetAtsOtherElse d_else(ReqOtherElse p_reqElse) throws Exception {
        String transType = p_reqElse.reqHeader.transType;
        String commandCode = p_reqElse.reqHeader.commandCode;

        if ("VerifySign".equals(transType)) {
            return verifyFnGrd(p_reqElse);
        } else if ("FGNATIVE04".equals(transType)) { //融汇通扫码支付（商户被扫）
            return getUrlFnGrd(p_reqElse);
        } else if ("FGNATIVE03".equals(transType)) { //融汇通扫码支付（商户主扫）
            return microPayFnGrd(p_reqElse);
        } else if ("JSAPI01".equals(transType)) {   //微信公众号（小程序支付）
            return getJSAPIUrl(p_reqElse);
        } else if ("VerifyBackNoticeSignFnGrd".equals(transType)) {
            return verifyBackNoticeSignFnGrd(p_reqElse);
        } else if ("VerifyBackNoticeSignWebapi".equals(transType)) {  //融汇webapi产品的支付结果通知
            return VerifyBackNoticeSignWebapi(p_reqElse);
        } else if ("QueryPayState".equals(transType)) {   //查询支付状态
            if ("JSAPI01".equals(commandCode) || "FGNATIVE01".equals(commandCode) || "FGNATIVE02".equals(commandCode)) { // 微信公众号支付||融汇通扫码支付（支付宝）||融汇通扫码支付（微信）
                return QueryWebAPIPay(p_reqElse);
            } else if ("FGNATIVE03".equals(commandCode)) {
                return WebApiAggregateMicroPayQuery(p_reqElse); //webapi聚合主扫
            } else {
                return queryFnGrdPay(p_reqElse);
            }
        } else if ("QueryRefundState".equals(transType)) {   //查询退款状态
            if ("JSAPI01".equals(commandCode) || "FGNATIVE01".equals(commandCode) || "FGNATIVE02".equals(commandCode) || "FGNATIVE03".equals(commandCode)) {
                return queryWebAPIRefund(p_reqElse);
            } else {
                return queryFnGrdRefund(p_reqElse);
            }
        } else if ("POS01".equals(transType)) {   //智能POS支付
            return posPay(p_reqElse);
        } else if ("PosQuery".equals(transType)) { //智能POS查询
            if ("PQ01".equals(commandCode)) {
                return verifyPosQuery(p_reqElse);
            } else {
                return signPosQuery(p_reqElse);
            }
        } else if ("PosNotify".equals(transType)) {  //智能POS通知验签
            if ("PS01".equals(commandCode)) {
                return verifyPosNotify(p_reqElse);
            } else {
                return signPosNotify(p_reqElse);
            }
        } else if ("Refund01".equals(transType)) {   //通用退款
            if ("JSAPI01".equals(commandCode) || "FGNATIVE01".equals(commandCode) || "FGNATIVE02".equals(commandCode) || "FGNATIVE03".equals(commandCode)) {
                return webAPIRefund(p_reqElse);
            } else {
                return refundApply(p_reqElse);
            }
        } else if ("SmartStorePay".equals(transType)) {  //智慧门店支付
            if ("FGNATIVE01".equals(commandCode)) { //融汇通扫码支付（微信）
                return WechatScanPay(p_reqElse);
            } else {  //融汇通扫码支付（支付宝）FGNATIVE02
                return AliScanPay(p_reqElse); //支付宝条码支付
            }
        } else if ("WebApiCloseOrder".equals(transType)) { //webapi关单
            return webAPICloseOrder(p_reqElse);
        } else if ("WebApiCancelOrder".equals(transType)) { //webapi撤单
            return webApiCancelOrder(p_reqElse);
        } else if ("WebApiAggregateMicroPay".equals(transType)) { //webapi聚合主扫
            return webApiAggregateMicroPay(p_reqElse);
        } else {
            RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

            retAts.retHashMap = new HashMap<String, String>();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", "未知的TransType：" + transType);

            return retAts;
        }
    }


    /**
     * 退款状态查询
     * <p>
     * 多种支付方式退款状态查询
     */
    public RetAtsOtherElse queryFnGrdRefund(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            //
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                FnGrd01Header bankHeader = new FnGrd01Header();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //erp单据号
                String reqNo = "";
                if (p_reqElse.reqHashMap.containsKey("ReqNo")) {
                    reqNo = p_reqElse.reqHashMap.get("ReqNo");
                }
                //退款流水号
                String refundNo = "";
                if (p_reqElse.reqHashMap.containsKey("RefundNo")) {
                    refundNo = p_reqElse.reqHashMap.get("RefundNo");
                }
                //请求码
                String transSeqID = "";
                if (p_reqElse.reqHashMap.containsKey("TransSeqID")) {
                    transSeqID = p_reqElse.reqHashMap.get("TransSeqID");
                }

                //组织机构号
                String comCode = "";
                if (p_reqElse.reqHashMap.containsKey("ComCode")) {
                    comCode = p_reqElse.reqHashMap.get("ComCode");
                }

                //退款方式
                String refundChannel = "";
                // 服务地址
                String url = "";
                if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    refundChannel = p_reqElse.reqHashMap.get("PosType");
                    url = bankFront.getUrl("posRefundUrl");
                } else {
                    refundChannel = getBankConfig().getMapValueByKey("refundChannel", p_reqElse.reqHeader.commandCode);
                    url = bankFront.getUrl("refundApplySubmit");
                }

                StringBuilder signStr = new StringBuilder();
                signStr.append(enterpriseNum).append("_");
                signStr.append(comCode).append("_");
                signStr.append(refundChannel).append("_");
                signStr.append(reqNo).append("_");
                signStr.append(refundNo);

                //签名
                String signature = signFnGrd(actItem, signStr.toString());

                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.writeStartElement("Root");
                xmlWriter.writeStartElement("Head");
                xmlWriter.writeElementString("EnterpriseNum", enterpriseNum);
                xmlWriter.writeElementString("CommandCode", "50004");
                xmlWriter.writeElementString("TransSeqID", transSeqID);
                xmlWriter.writeElementString("VerifyCode", signature);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("RefundQueryRequest");
                xmlWriter.writeElementString("ComCode", comCode);
                xmlWriter.writeElementString("RefundChannel", refundChannel);
                xmlWriter.writeElementString("ReqNo", reqNo);
                xmlWriter.writeElementString("RefundNo", refundNo);
                xmlWriter.writeEndDocument();

                String reqSendData = getReqSendData(enterpriseNum, xmlWriter.toXmlString(), "GBK");

                String tmpRetStr = sendUnifiedToBank(reqSendData, url);
                //解密获得的返回参数
                String respData = this.getRespPostData(tmpRetStr, "GBK", "");

                //解析返回的xml报文
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(respData, tmpSbMsg);
                if (tmpBkReader != null) {
                    //判断交易的支付状态
                    String respCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    //头部 RespCode 为 0，存在业务报文，且 TransState 值为 3，判定为交易失败
                    //头部 RespCode 为 0，存在业务报文，且 TransState 值为 2，判定为交易成功
                    //头部 RespCode 为 -1，判定为交易未知
                    if (respCode == null || "".equals(respCode)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "渠道返回的Respode为空");
                        WriteBankLogLn2("渠道返回的RespCode为空");
                    } else {
                        //RespCode 为 -1的时候不验签，RespCode 为 0的时候验签
                        if ("0".equals(respCode)) {
                            String enterpriseNumRet = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                            String verifyCode = tmpBkReader.getFirstText("/Root/Head/VerifyCode");
                            String comCodeRet = tmpBkReader.getFirstText("/Root/RefundQueryResponse/ComCode");
                            String refundChannelRet = tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundChannel");
                            String reqNoRet = tmpBkReader.getFirstText("/Root/RefundQueryResponse/ReqNo");
                            String refundNoRet = tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundNo");
                            String refundFeeRet = tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundFee");
                            String refundStateRet = tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundState");
                            //验签字符串--企业编号_组织机构号_退款方式_交易流水_退款单号_退款金额_退款状态
                            StringBuilder signStrRtn = new StringBuilder();
                            signStrRtn.append(enterpriseNumRet).append("_");
                            signStrRtn.append(comCodeRet).append("_");
                            signStrRtn.append(refundChannelRet).append("_");
                            signStrRtn.append(reqNoRet).append("_");
                            signStrRtn.append(refundNoRet).append("_");
                            signStrRtn.append(refundFeeRet).append("_");
                            signStrRtn.append(refundStateRet);

                            // 执行验签
                            boolean verifySignResult = verifyFnGrd(signStrRtn.toString(), verifyCode, actItem);
                            if (verifySignResult) {
                                WriteBankLogLn2("验证签名成功");
                                if (refundStateRet == null || "".equals(refundStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易未知");
                                } else if ("2".equals(refundStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易成功");
                                    fillRefundReturnData(retAts, tmpBkReader);
                                } else if ("3".equals(refundStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易失败");
                                    fillRefundReturnData(retAts, tmpBkReader);
                                } else if ("4".equals(refundStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易中");
                                    fillRefundReturnData(retAts, tmpBkReader);
                                } else {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "渠道返回非法，值为：" + refundStateRet);
                                    fillRefundReturnData(retAts, tmpBkReader);
                                }
                            } else {
                                retAts.retHashMap.put("RespCode", "0");
                                retAts.retHashMap.put("RespInfo", "验证签名失败");
                            }
                        } else if ("-1".equals(respCode)) {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "交易未知,请稍后查询交易单状态");
                            WriteBankLogLn2("交易未知,请稍后查询交易单状态");
                        } else {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "融合付返回的Respode非法，值为" + respCode);
                            WriteBankLogLn2("返回的RespCode非法");
                        }
                    }
                }

            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    /**
     * 主扫、被扫、POS退款
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse refundApply(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            //
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                FnGrd01Header bankHeader = new FnGrd01Header();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //erp单据号
                String reqNo = "";
                if (p_reqElse.reqHashMap.containsKey("ReqNo")) {
                    reqNo = p_reqElse.reqHashMap.get("ReqNo");
                }
                //原收款单的交易流水
                String OrderId = "";
                if (p_reqElse.reqHashMap.containsKey("OrderId")) {
                    OrderId = p_reqElse.reqHashMap.get("OrderId");
                }
                //退款单的交易流水
                String refundNo = "";
                if (p_reqElse.reqHashMap.containsKey("RefundNo")) {
                    refundNo = p_reqElse.reqHashMap.get("RefundNo");
                }
                //退款金额
                String refundFee = "";
                if (p_reqElse.reqHashMap.containsKey("RefundFee")) {
                    refundFee = p_reqElse.reqHashMap.get("RefundFee");
                }

                //请求码
                String transSeqID = "";
                if (p_reqElse.reqHashMap.containsKey("TransSeqID")) {
                    transSeqID = p_reqElse.reqHashMap.get("TransSeqID");
                }

                //到期时间     yyyyMMddHHmmss
                String expireTime = "";
                if (p_reqElse.reqHashMap.containsKey("ExpireTime")) {
                    expireTime = p_reqElse.reqHashMap.get("ExpireTime");
                }

                //组织机构号
                String comCode = "";
                if (p_reqElse.reqHashMap.containsKey("ComCode")) {
                    comCode = p_reqElse.reqHashMap.get("ComCode");
                }

                //后台通知地址
                String refundNotifyURL = "";
                //退款方式
                String refundChannel = "";
                // 服务地址
                String url = "";
                if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    refundChannel = p_reqElse.reqHashMap.get("PosType");
                    url = bankFront.getUrl("posRefundUrl");
                    refundNotifyURL = actItem.posRefundNotifyURL;
                } else {
                    refundChannel = getBankConfig().getMapValueByKey("refundChannel", p_reqElse.reqHeader.commandCode);
                    url = bankFront.getUrl("refundApplySubmit");
                    refundNotifyURL = actItem.refundNotifyURL;
                }

                // 获取签名字符串--企业编号_组织机构号_退款方式_交易流水号_退款单号_退款金额_后台通知地址
                //目前组织机构号，就取商户号值
                StringBuilder signStr = new StringBuilder();
                signStr.append(enterpriseNum).append("_");
                signStr.append(comCode).append("_");
                signStr.append(refundChannel).append("_");
                signStr.append(reqNo).append("_");
                signStr.append(refundNo).append("_");
                signStr.append(refundFee).append("_");
                signStr.append(refundNotifyURL);

                //签名
                String signature = signFnGrd(actItem, signStr.toString());

                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.writeStartElement("Root");
                xmlWriter.writeStartElement("Head");
                xmlWriter.writeElementString("EnterpriseNum", enterpriseNum);
                xmlWriter.writeElementString("CommandCode", "50003");
                xmlWriter.writeElementString("TransSeqID", transSeqID);
                xmlWriter.writeElementString("VerifyCode", signature);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("RefundRequest");
                xmlWriter.writeElementString("ComCode", comCode);
                xmlWriter.writeElementString("RefundChannel", refundChannel);
                xmlWriter.writeElementString("ReqNo", reqNo);
                xmlWriter.writeElementString("OrderId", OrderId);
                xmlWriter.writeElementString("RefundNo", refundNo);
                xmlWriter.writeElementString("RefundFee", refundFee);
                xmlWriter.writeElementString("NoticeUrl", refundNotifyURL);
                xmlWriter.writeElementString("ExpireTime", expireTime);
                xmlWriter.writeElementString("MchId", merchantId);
                xmlWriter.writeEndDocument();

                String reqSendData = getReqSendData(enterpriseNum, xmlWriter.toXmlString(), "GBK");


                if (StringHelper.isNullOrEmpty(url)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "融合付退款申请服务地址为空,请检查BankFront.xml相关配置!");
                    return retAts;
                }
                String tmpRetStr = sendUnifiedToBank(reqSendData, url);
                //解密获得的返回参数
                String respData = this.getRespPostData(tmpRetStr, "GBK", "");
                //解析返回的xml报文
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(respData, tmpSbMsg);
                if (tmpBkReader != null) {
                    //判断交易的支付状态
                    String respCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    //头部 RespCode 为 0，存在业务报文，且 AcceptCode 值为非 0，判定为受理失败。头部的 RespCode 为 0，但不存在业务报文，判断为受理失败
                    //头部 RespCode 为 0，存在业务报文，且 AcceptCode值为 0，判定为受理成功
                    //当头部 RespCode 为 -1 时，判断为受理未知
                    if (respCode == null || "".equals(respCode)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "渠道返回的Respode为空");
                        WriteBankLogLn2("渠道返回的RespCode为空");
                    } else {
                        //RespCode 为 -1的时候不验签，RespCode 为 0的时候验签
                        if ("0".equals(respCode)) {

                            String enterpriseNumRtn = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                            String verifyCode = tmpBkReader.getFirstText("/Root/Head/VerifyCode");
                            String reqNoRtn = tmpBkReader.getFirstText("/Root/RefundResponse/ReqNo");
                            String refundNoRtn = tmpBkReader.getFirstText("/Root/RefundResponse/RefundNo");
                            String acceptCode = tmpBkReader.getFirstText("/Root/RefundResponse/AcceptCode");
                            String acceptMessage = tmpBkReader.getFirstText("/Root/RefundResponse/AcceptMessage");
                            //验证返回报文中的签名信息--企业号_交易流水_退款单号_受理状态
                            StringBuilder signStrRtn = new StringBuilder();
                            signStrRtn.append(enterpriseNumRtn).append("_");
                            signStrRtn.append(reqNoRtn).append("_");
                            signStrRtn.append(refundNoRtn).append("_");
                            signStrRtn.append(acceptCode);

                            // 执行验签
                            boolean verifySignResult = verifyFnGrd(signStrRtn.toString(), verifyCode, actItem);
                            if (verifySignResult) {
                                WriteBankLogLn2("验证签名成功");
                                if (acceptCode == null || "".equals(acceptCode)) {
                                    retAts.retHashMap.put("RespCode", "-1");
                                    retAts.retHashMap.put("RespInfo", "交易未知");
                                } else if ("0".equals(acceptCode)) {
                                    retAts.retHashMap.put("RespCode", "SUCCESS");
                                    retAts.retHashMap.put("RespInfo", "受理成功");
                                    //交易流水
                                    retAts.retHashMap.put("ReqNo", tmpBkReader.getFirstText("/Root/RefundResponse/ReqNo"));
                                    //退款单号
                                    retAts.retHashMap.put("RefundNo", tmpBkReader.getFirstText("/Root/RefundResponse/RefundNo"));
                                    //受理状态
                                    retAts.retHashMap.put("AcceptCode", tmpBkReader.getFirstText("/Root/RefundResponse/AcceptCode"));
                                    //受理信息
                                    retAts.retHashMap.put("AcceptMessage", tmpBkReader.getFirstText("/Root/RefundResponse/AcceptMessage"));
                                } else {
                                    retAts.retHashMap.put("RespCode", "FAILURE");
                                    retAts.retHashMap.put("RespInfo", "受理失败");
                                    //交易流水
                                    retAts.retHashMap.put("ReqNo", tmpBkReader.getFirstText("/Root/RefundResponse/ReqNo"));
                                    //退款单号
                                    retAts.retHashMap.put("RefundNo", tmpBkReader.getFirstText("/Root/RefundResponse/RefundNo"));
                                    //受理状态
                                    retAts.retHashMap.put("AcceptCode", tmpBkReader.getFirstText("/Root/RefundResponse/AcceptCode"));
                                    //受理信息
                                    retAts.retHashMap.put("AcceptMessage", tmpBkReader.getFirstText("/Root/RefundResponse/AcceptMessage"));
                                }
                            } else {
                                retAts.retHashMap.put("RespCode", "0");
                                retAts.retHashMap.put("RespInfo", "验证签名失败");
                            }
                        } else if ("-1".equals(respCode)) {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "交易未知,请稍后查询交易单状态");
                            WriteBankLogLn2("交易未知,请稍后查询交易单状态");
                        } else {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "融合付返回的Respode非法，值为" + respCode);
                            WriteBankLogLn2("返回的RespCode非法");
                        }
                    }
                }
            } else {
                retAts.retHashMap.put("RespCode", "FAILURE");//跟易企收原先的判断逻辑一致，置为FAILURE
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "0");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }

    /**
     * 融汇通知返回验签
     *
     * @param p_reqElse 验签请求对象
     * @return 验签结果
     */
    public RetAtsOtherElse verifyFnGrd(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            String ownAct = "";
            if (p_reqElse.reqHashMap.containsKey("OurBankAccount")) {
                ownAct = p_reqElse.reqHashMap.get("OurBankAccount");
            }

            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }

            String appId = "";
            if (p_reqElse.reqHashMap.containsKey("AppId")) {
                appId = p_reqElse.reqHashMap.get("AppId");
            }

            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("Plain")) {
                plain = p_reqElse.reqHashMap.get("Plain");
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失验签原始串");

                return retAts;
            }

            ActSetItem actItem = getBankConfig().getActSetItemByAny(ownAct, merchantId, appId, "unifiedorder");
            if (actItem != null) {
                String[] fnGrdSign = getNewFnGrdSign(plain, actItem.saltKey);
//                String[] fnGrdSign = getFnGrdSign(plain, p_reqElse.reqHeader.commandCode, actItem.saltKey);

                WriteBankLogLn2("融汇返回待签名数据:\r\n" + fnGrdSign[0]);
                WriteBankLogLn2("融汇返回签名:\r\n" + fnGrdSign[1]);

                // 执行验签
                boolean verifySignResult = verifyFnGrd(fnGrdSign[0], fnGrdSign[1], actItem);
                if (verifySignResult) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到账号[" + ownAct + "]商户配置信息!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    /**
     * 融汇远程付
     *
     * @param p_reqElse 远程付请求对象
     * @return 远程付请求地址+参数
     */
    public RetAtsOtherElse getUrlFnGrd(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            //
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                FnGrd01Header bankHeader = new FnGrd01Header();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //缴费单号
                String exchangeNo = "";
                if (p_reqElse.reqHashMap.containsKey("ExchangeNo")) {
                    exchangeNo = p_reqElse.reqHashMap.get("ExchangeNo");
                }
                //金额
                String amount = "";
                String discountAmount = "0.00";
                if (p_reqElse.reqHashMap.containsKey("Amount")) {
                    amount = p_reqElse.reqHashMap.get("Amount");
                }
                //前台通知地址
                String callBackUrl = actItem.returnURL;
                //重新发起请求地址
                String reSendUrl = actItem.resendURL;
                //后台通知地址
                String noticeUrl = actItem.notifyURL;
                //备注
                String memo = "";
                if (p_reqElse.reqHashMap.containsKey("Memo")) {
                    memo = p_reqElse.reqHashMap.get("Memo");
                }
                //扩展字段1
                String extent1 = "";
                if (p_reqElse.reqHashMap.containsKey("Extent1")) {
                    extent1 = p_reqElse.reqHashMap.get("Extent1");
                }
                //扩展字段2
                String extent2 = "";
                if (p_reqElse.reqHashMap.containsKey("Extent2")) {
                    extent2 = p_reqElse.reqHashMap.get("Extent2");
                }

                //请求码
                String transSeqID = "";
                if (p_reqElse.reqHashMap.containsKey("TransSeqID")) {
                    transSeqID = p_reqElse.reqHashMap.get("TransSeqID");
                }

                // 获取签名字符串
                StringBuilder signStr = new StringBuilder();
                signStr.append(enterpriseNum).append("_");
                signStr.append(exchangeNo).append("_");
                signStr.append(exchangeNo).append("_");
                signStr.append("0").append("_");
                signStr.append("0").append("_");
                signStr.append(amount).append("_");
                signStr.append(discountAmount).append("_");
                signStr.append("0").append("_");
                signStr.append(callBackUrl).append("_");
                signStr.append(noticeUrl).append("_");
                signStr.append(reSendUrl);
                //签名
                String signature = signFnGrd(actItem, signStr.toString());

                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.writeStartElement("Root");
                xmlWriter.writeStartElement("Head");
                xmlWriter.writeElementString("EnterpriseNum", enterpriseNum);
                xmlWriter.writeElementString("CommandCode", "10001");
                xmlWriter.writeElementString("TransSeqID", transSeqID);
                xmlWriter.writeElementString("VerifyCode", signature);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("TransRequest");
                xmlWriter.writeElementString("ReqNo", exchangeNo);
                xmlWriter.writeElementString("ExchangeNo", exchangeNo);
                xmlWriter.writeElementString("CustName", "0");
                xmlWriter.writeElementString("CertType", "0");
                xmlWriter.writeElementString("CertNum", "0");
                xmlWriter.writeElementString("PhoneNum", "");
                xmlWriter.writeElementString("Amount", amount);
                xmlWriter.writeElementString("DiscountAmount", discountAmount);
                xmlWriter.writeElementString("CarNum", "");
                xmlWriter.writeElementString("ComCode", merchantId);
                xmlWriter.writeElementString("CertiNo", "");
                xmlWriter.writeElementString("CallFlag", "0");
                String paymentChannel = getBankConfig().getMapValueByKey("statementType", "paymentChannel");
                xmlWriter.writeElementString("Channel", paymentChannel);
                xmlWriter.writeElementString("Memo", memo);
                xmlWriter.writeElementString("IsCheckIdentity", "0");
                xmlWriter.writeElementString("CallBackUrl", callBackUrl);
                xmlWriter.writeElementString("NoticeUrl", noticeUrl);
                xmlWriter.writeElementString("ReSendUrl", reSendUrl);
                xmlWriter.writeElementString("Extent1", extent1);
                xmlWriter.writeElementString("Extent2", extent2);
                xmlWriter.writeEndDocument();

                String reqSendData = getReqSendData(enterpriseNum, xmlWriter.toXmlString(), "GBK");

                // 服务地址
                String url = bankFront.getUrl("submitFGQROrder");
                if (StringHelper.isNullOrEmpty(url)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "融汇远程付网关服务地址为空,请检查BankFront.xml相关配置!");
                    return retAts;
                }
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", url + "?" + reqSendData);

            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    /**
     * 刷卡支付（扫码枪）（商户扫客户）
     *
     * @param p_reqElse 统一扫码支付（商户扫客户）请求对象
     * @return 统一扫码支付（商户扫客户）支付结果
     */
    public RetAtsOtherElse microPayFnGrd(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            //
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                FnGrd01Header bankHeader = new FnGrd01Header();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //缴费单号
                String reqNo = "";
                if (p_reqElse.reqHashMap.containsKey("ReqNo")) {
                    reqNo = p_reqElse.reqHashMap.get("ReqNo");
                }
                //扫码支付授权码
                String authCode = "";
                if (p_reqElse.reqHashMap.containsKey("AuthCode")) {
                    authCode = p_reqElse.reqHashMap.get("AuthCode");
                }
                //姓名，没有可填0
                String custName = "0";
                if (p_reqElse.reqHashMap.containsKey("CustName")) {
                    custName = p_reqElse.reqHashMap.get("CustName");
                }
                //证件类型枚举，默认身份证0
                String certType = "0";
                if (p_reqElse.reqHashMap.containsKey("CertType")) {
                    certType = p_reqElse.reqHashMap.get("CertType");
                }
                //证件号，没有可填0
                String certNum = "0";
                if (p_reqElse.reqHashMap.containsKey("CertNum")) {
                    certNum = p_reqElse.reqHashMap.get("CertNum");
                }
                //手机号
                String phoneNum = "";
                if (p_reqElse.reqHashMap.containsKey("PhoneNum")) {
                    phoneNum = p_reqElse.reqHashMap.get("PhoneNum");
                }
                //金额
                String amount = "";
                if (p_reqElse.reqHashMap.containsKey("Amount")) {
                    amount = p_reqElse.reqHashMap.get("Amount");
                }
                //商品描述
                String goodDesc = "";
                if (p_reqElse.reqHashMap.containsKey("GoodDesc")) {
                    goodDesc = p_reqElse.reqHashMap.get("GoodDesc");
                }
                //操作员编号
                String opUserId = "";
                if (p_reqElse.reqHashMap.containsKey("OpUserId")) {
                    opUserId = p_reqElse.reqHashMap.get("OpUserId");
                }
                //门店编号
                String opShopId = "";
                if (p_reqElse.reqHashMap.containsKey("OpShopId")) {
                    opShopId = p_reqElse.reqHashMap.get("OpShopId");
                }
                //设备编号
                String opDeviceId = "";
                if (p_reqElse.reqHashMap.containsKey("OpDeviceId")) {
                    opDeviceId = p_reqElse.reqHashMap.get("OpDeviceId");
                }
                //后台通知地址
                //后台通知地址
                //String noticeUrl = actItem.backnotifyURL;
                /*String noticeUrl = "";
                if (p_reqElse.reqHashMap.containsKey("NoticeUrl")) {
                    noticeUrl = p_reqElse.reqHashMap.get("NoticeUrl");
                }*/
                //备注
                String memo = "";
                if (p_reqElse.reqHashMap.containsKey("Memo")) {
                    memo = p_reqElse.reqHashMap.get("Memo");
                }
                //扩展字段1
                String extent1 = "";
                if (p_reqElse.reqHashMap.containsKey("Extent1")) {
                    extent1 = p_reqElse.reqHashMap.get("Extent1");
                }
                //扩展字段2
                String extent2 = "";
                if (p_reqElse.reqHashMap.containsKey("Extent2")) {
                    extent2 = p_reqElse.reqHashMap.get("Extent2");
                }

                //请求码
                String transSeqID = "";
                if (p_reqElse.reqHashMap.containsKey("TransSeqID")) {
                    transSeqID = p_reqElse.reqHashMap.get("TransSeqID");
                }

                //到期时间     yyyyMMddHHmmss
                String expireTime = "";
                if (p_reqElse.reqHashMap.containsKey("ExpireTime")) {
                    expireTime = p_reqElse.reqHashMap.get("ExpireTime");
                }

                //组织机构号
                String comCode = "";
                if (p_reqElse.reqHashMap.containsKey("ComCode")) {
                    comCode = p_reqElse.reqHashMap.get("ComCode");
                }
                // 获取签名字符串--企业编号_请求流水号_支付授权码_姓名_证件号_缴费总金额
                String signature = getSignStr(actItem, enterpriseNum, reqNo, authCode, custName, certNum, amount, comCode);

                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.writeStartElement("Root");
                xmlWriter.writeStartElement("Head");
                xmlWriter.writeElementString("EnterpriseNum", enterpriseNum);
                xmlWriter.writeElementString("CommandCode", "10001");
                xmlWriter.writeElementString("TransSeqID", transSeqID);
                xmlWriter.writeElementString("VerifyCode", signature);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("TransRequest");
                xmlWriter.writeElementString("ReqNo", reqNo);
                xmlWriter.writeElementString("ComCode", comCode);
                xmlWriter.writeElementString("AuthCode", authCode);
                xmlWriter.writeElementString("CustName", custName);
                xmlWriter.writeElementString("CertType", certType);
                xmlWriter.writeElementString("CertNum", certNum);
                xmlWriter.writeElementString("PhoneNum", phoneNum);
                xmlWriter.writeElementString("Amount", amount);
                xmlWriter.writeElementString("GoodDesc", goodDesc);
                xmlWriter.writeElementString("OpUserId", opUserId);
                xmlWriter.writeElementString("OpShopId", opShopId);
                xmlWriter.writeElementString("OpDeviceId", opDeviceId);
                xmlWriter.writeElementString("MchId", merchantId);
                xmlWriter.writeElementString("Extent1", extent1);
                xmlWriter.writeElementString("Extent2", extent2);
                xmlWriter.writeElementString("ExpireTime", expireTime);
                xmlWriter.writeEndDocument();

                String reqSendData = getReqSendData(enterpriseNum, xmlWriter.toXmlString(), "GBK");

                // 服务地址
                String url = bankFront.getUrl("microPayOrderSubmit");
                if (StringHelper.isNullOrEmpty(url)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "统一扫码支付(商户扫客户)下单服务地址为空,请检查BankFront.xml相关配置!");
                    return retAts;
                }
                String tmpRetStr = sendUnifiedToBank(reqSendData, url);
                //解密获得的返回参数
                String respData = this.getRespPostData(tmpRetStr, "GBK", "MicroPayFnGrd");
                //解析返回的xml报文
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(respData, tmpSbMsg);
                if (tmpBkReader != null) {
                    //判断交易的支付状态
                    String respCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    //头部 RespCode 为 0，存在业务报文，且 TransState 值为 3，判定为交易失败
                    //头部 RespCode 为 0，存在业务报文，且 TransState 值为 2，判定为交易成功
                    //头部 RespCode 为 -1，判定为交易未知
                    if (respCode == null || "".equals(respCode)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "渠道返回的Respode为空");
                        WriteBankLogLn2("渠道返回的RespCode为空");
                    } else {
                        //RespCode 为 -1的时候不验签，RespCode 为 0的时候验签
                        if ("0".equals(respCode)) {
                            //验证返回报文中的签名信息--企业编号_请求流水号_金额_交易状态
                            String enterpriseNumRet = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                            String verifyCode = tmpBkReader.getFirstText("/Root/Head/VerifyCode");
                            String reqNoRet = tmpBkReader.getFirstText("/Root/TransResponse/ReqNo");
                            String amountRet = tmpBkReader.getFirstText("/Root/TransResponse/Amount");
                            String transStateRet = tmpBkReader.getFirstText("/Root/TransResponse/TransState");

                            StringBuilder signStrRtn = new StringBuilder();
                            signStrRtn.append(enterpriseNumRet).append("_");
                            signStrRtn.append(reqNoRet).append("_");
                            signStrRtn.append(amountRet).append("_");
                            signStrRtn.append(transStateRet);


                            // 执行验签
                            boolean verifySignResult = verifyFnGrd(signStrRtn.toString(), verifyCode, actItem);
                            if (verifySignResult) {
                                WriteBankLogLn2("验证签名成功");
                                if (transStateRet == null || "".equals(transStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易未知");
                                } else if ("2".equals(transStateRet)) {
                                    retAts.retHashMap.put("RespCode", "SUCCESS");
                                    retAts.retHashMap.put("RespInfo", "交易成功");
                                    fillReturnData(retAts, tmpBkReader);
                                } else if ("3".equals(transStateRet)) {
                                    retAts.retHashMap.put("RespCode", "FAILURE");
                                    retAts.retHashMap.put("RespInfo", "交易失败");
                                    fillReturnData(retAts, tmpBkReader);
                                } else {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易未知,渠道返回非法，值为：" + transStateRet);
                                }
                            } else {
                                retAts.retHashMap.put("RespCode", "0");
                                retAts.retHashMap.put("RespInfo", "验证签名失败");
                            }
                        } else if ("-1".equals(respCode)) {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "交易未知,请稍后查询交易单状态");
                            WriteBankLogLn2("交易未知,请稍后查询交易单状态");
                        } else {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "融合付返回的Respode非法，值为" + respCode);
                            WriteBankLogLn2("返回的RespCode非法");
                        }
                    }
                }
            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "0");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    private void fillReturnData(RetAtsOtherElse retAts, XmlTextReader tmpBkReader) throws Exception {
        //请求流水号，需要保证唯一
        retAts.retHashMap.put("ReqNo", tmpBkReader.getFirstText("/Root/TransResponse/ReqNo"));
        //交易实付金额（元，精确到小数两位）
        retAts.retHashMap.put("Amount", tmpBkReader.getFirstText("/Root/TransResponse/Amount"));
        //支付状态
        retAts.retHashMap.put("TransState", tmpBkReader.getFirstText("/Root/TransResponse/TransState"));
        //交易返回码
        retAts.retHashMap.put("TransInfoCode", tmpBkReader.getFirstText("/Root/TransResponse/TransInfoCode"));
        //返回码对应的详细文字描述
        retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/TransInfo"));
        //交易成功时间
        retAts.retHashMap.put("TransTime", tmpBkReader.getFirstText("/Root/TransResponse/TransTime"));
        //第三方订单号（实际支付渠道流水号）
        retAts.retHashMap.put("OutTransactionId", tmpBkReader.getFirstText("/Root/TransResponse/OutTransactionId"));
        //缴费账户对应姓名
        retAts.retHashMap.put("CustName", tmpBkReader.getFirstText("/Root/TransResponse/CustName"));
        //证件类型枚举
        retAts.retHashMap.put("CertType", tmpBkReader.getFirstText("/Root/TransResponse/CertType"));
        //缴费账户对应证件号
        retAts.retHashMap.put("CertNum", tmpBkReader.getFirstText("/Root/TransResponse/CertNum"));
        //手机号
        retAts.retHashMap.put("PhoneNum", tmpBkReader.getFirstText("/Root/TransResponse/PhoneNum"));
        //商品描述
        retAts.retHashMap.put("GoodDesc", tmpBkReader.getFirstText("/Root/TransResponse/GoodDesc"));
        //扩展字段1
        retAts.retHashMap.put("Extent1", tmpBkReader.getFirstText("/Root/TransResponse/Extent1"));
        //扩展字段2
        retAts.retHashMap.put("Extent2", tmpBkReader.getFirstText("/Root/TransResponse/Extent2"));
        //到期时间
        retAts.retHashMap.put("ExpireTime", tmpBkReader.getFirstText("/Root/TransResponse/ExpireTime"));
        String tmpCustBankCode = tmpBkReader.getFirstText("/Root/TransResponse/CustBankCode");
        String bankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", tmpCustBankCode);
        if (StringUtils.isNotEmpty(bankCode)) {
            tmpCustBankCode = bankCode;
        }
        //交易银行代码
        retAts.retHashMap.put("CustBankCode", tmpCustBankCode);
        retAts.retHashMap.put("CustAccount", tmpBkReader.getFirstText("/Root/TransResponse/CustAccount"));
        //支付方式，POS支付查询接口返回
        retAts.retHashMap.put("PayType", tmpBkReader.getFirstText("/Root/TransResponse/PayType"));
    }

    private void fillRefundReturnData(RetAtsOtherElse retAts, XmlTextReader tmpBkReader) throws Exception {
        //退款查询返回参数
        //商户号
        retAts.retHashMap.put("MerchantId", tmpBkReader.getFirstText("/Root/RefundQueryResponse/ComCode"));
        //退款方式
        retAts.retHashMap.put("RefundChannel", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundChannel"));
        //交易流水
        retAts.retHashMap.put("ReqNo", tmpBkReader.getFirstText("/Root/RefundQueryResponse/ReqNo"));
        //退款单号
        retAts.retHashMap.put("RefundNo", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundNo"));
        //退款金额
        retAts.retHashMap.put("RefundFee", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundFee"));
        //退款状态
        retAts.retHashMap.put("RefundState", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundState"));
        //退款成功时间
        retAts.retHashMap.put("RefundTime", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundTime"));
        //退款返回码
        retAts.retHashMap.put("RefundInfoCode", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundInfoCode"));
        //退款结果描述
        retAts.retHashMap.put("RefundInfo", tmpBkReader.getFirstText("/Root/RefundQueryResponse/RefundInfo"));
        //到期时间
        retAts.retHashMap.put("ExpireTime", tmpBkReader.getFirstText("/Root/RefundQueryResponse/ExpireTime"));
    }

    /**
     * 缴费状态查询
     *
     * @param p_reqElse 统一扫码支付（商户扫客户）请求对象
     * @return 统一扫码支付支付结果
     */
    public RetAtsOtherElse queryFnGrdPay(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            //
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                FnGrd01Header bankHeader = new FnGrd01Header();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //缴费单号
                String exchangeNo = "";
                if (p_reqElse.reqHashMap.containsKey("ExchangeNo")) {
                    exchangeNo = p_reqElse.reqHashMap.get("ExchangeNo");
                }
                //订单编号
                String orderId = "";
                if (p_reqElse.reqHashMap.containsKey("OrderId")) {
                    orderId = p_reqElse.reqHashMap.get("OrderId");
                }
                //请求码
                String transSeqID = "";
                if (p_reqElse.reqHashMap.containsKey("TransSeqID")) {
                    transSeqID = p_reqElse.reqHashMap.get("TransSeqID");
                }
                // 获取签名字符串
                StringBuilder signStr = new StringBuilder();
                if ("FGNATIVE03".equals(p_reqElse.reqHeader.commandCode)) {
                    signStr.append(enterpriseNum).append("_");
                    signStr.append(exchangeNo);
                } else if ("FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                    signStr.append(enterpriseNum).append("_");
                    signStr.append(exchangeNo).append("_");
                    signStr.append(exchangeNo);
                } else if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    signStr.append(enterpriseNum).append("_");
                    signStr.append(exchangeNo).append("_");
                    signStr.append(orderId);
                }


                //签名
                String signature = signFnGrd(actItem, signStr.toString());

                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.writeStartElement("Root");
                xmlWriter.writeStartElement("Head");
                xmlWriter.writeElementString("EnterpriseNum", enterpriseNum);
                if ("FGNATIVE03".equals(p_reqElse.reqHeader.commandCode)) {
                    xmlWriter.writeElementString("CommandCode", "60002");
                } else if ("FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                    xmlWriter.writeElementString("CommandCode", "20001");
                } else if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    xmlWriter.writeElementString("CommandCode", "70002");
                }

                xmlWriter.writeElementString("TransSeqID", transSeqID);
                xmlWriter.writeElementString("VerifyCode", signature);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("TransQueryRequest");
                xmlWriter.writeElementString("ReqNo", exchangeNo);
                if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    xmlWriter.writeElementString("OrderId", orderId);
                }
                if ("FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                    xmlWriter.writeElementString("ExchangeNo", exchangeNo);
                }
                xmlWriter.writeEndDocument();

                String reqSendData = getReqSendData(enterpriseNum, xmlWriter.toXmlString(), "GBK");

                // 服务地址
                String url = "";
                if ("FGNATIVE03".equals(p_reqElse.reqHeader.commandCode)) {
                    url = bankFront.getUrl("microPayOrderQuery");
                    if (StringHelper.isNullOrEmpty(url)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "统一扫码支付(商户扫客户)查询服务地址为空,请检查BankFront.xml相关配置!");
                        return retAts;
                    }
                } else if ("FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                    url = bankFront.getUrl("submitFGQROrder");
                    if (StringHelper.isNullOrEmpty(url)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "融汇远程付查询服务地址为空,请检查BankFront.xml相关配置!");
                        return retAts;
                    }
                } else if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    url = bankFront.getUrl("posPayOrderSubmit");
                    if (StringHelper.isNullOrEmpty(url)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "POS支付查询服务地址为空,请检查BankFront.xml相关配置!");
                        return retAts;
                    }
                }

                String tmpRetStr = sendUnifiedToBank(reqSendData, url);
                //解密获得的返回参数
                String respData = "";
                if ("FGNATIVE03".equals(p_reqElse.reqHeader.commandCode) || "FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                    respData = this.getRespPostData(tmpRetStr, "GBK", "QueryPayState");
                } else if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    respData = this.getRespPostData(tmpRetStr, "GBK", "");
                }

                //解析返回的xml报文
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(respData, tmpSbMsg);
                if (tmpBkReader != null) {
                    //判断交易的支付状态
                    String respCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    //头部 RespCode 为 0，存在业务报文，且 TransState 值为 3，判定为交易失败
                    //头部 RespCode 为 0，存在业务报文，且 TransState 值为 2，判定为交易成功
                    //头部 RespCode 为 -1，判定为交易未知
                    if (respCode == null || "".equals(respCode)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "渠道返回的Respode为空");
                        WriteBankLogLn2("渠道返回的RespCode为空");
                    } else {
                        //RespCode 为 -1的时候不验签，RespCode 为 0的时候验签
                        if ("0".equals(respCode)) {
                            //验证返回报文中的签名信息--企业编号_请求流水号_金额_交易状态
                            String enterpriseNumRet = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                            String verifyCode = tmpBkReader.getFirstText("/Root/Head/VerifyCode");
                            String reqNoRet = tmpBkReader.getFirstText("/Root/TransResponse/ReqNo");
                            String amountRet = tmpBkReader.getFirstText("/Root/TransResponse/Amount");
                            String transStateRet = tmpBkReader.getFirstText("/Root/TransResponse/TransState");

                            StringBuilder signStrRtn = new StringBuilder();
                            if ("FGNATIVE03".equals(p_reqElse.reqHeader.commandCode)) {
                                signStrRtn.append(enterpriseNumRet).append("_");
                                signStrRtn.append(reqNoRet).append("_");
                                signStrRtn.append(amountRet).append("_");
                                signStrRtn.append(transStateRet);
                            } else if ("FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                                String feedbackStateRet = tmpBkReader.getFirstText("/Root/TransResponse/FeedbackState");
                                signStrRtn.append(enterpriseNumRet).append("_");
                                signStrRtn.append(reqNoRet).append("_");
                                signStrRtn.append(reqNoRet).append("_");
                                signStrRtn.append(amountRet).append("_");
                                signStrRtn.append(transStateRet).append("_");
                                signStrRtn.append(feedbackStateRet);
                            } else if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                                //企业编号_交易流水号_订单编号_门店编号_收款员编号_POS类型_POS编号_交易类型_金额_交易状态_银行卡号
                                String shopNum = tmpBkReader.getFirstText("/Root/TransResponse/ShopNum");
                                String speratorID = tmpBkReader.getFirstText("/Root/TransResponse/OperatorID");
                                String posType = tmpBkReader.getFirstText("/Root/TransResponse/PosType");
                                String posID = tmpBkReader.getFirstText("/Root/TransResponse/PosID");
                                String transType = tmpBkReader.getFirstText("/Root/TransResponse/TransType");
                                String orderIdRet = tmpBkReader.getFirstText("/Root/TransResponse/OrderId");
                                String bankCardNo = tmpBkReader.getFirstText("/Root/TransResponse/BankCardNo");
                                signStrRtn.append(enterpriseNumRet).append("_");
                                signStrRtn.append(reqNoRet).append("_");
                                signStrRtn.append(orderIdRet).append("_");
                                signStrRtn.append(shopNum).append("_");
                                signStrRtn.append(speratorID).append("_");
                                signStrRtn.append(posType).append("_");
                                signStrRtn.append(posID).append("_");
                                signStrRtn.append(transType).append("_");
                                signStrRtn.append(amountRet).append("_");
                                signStrRtn.append(transStateRet).append("_");
                                signStrRtn.append(bankCardNo);
                            }


                            // 执行验签
                            boolean verifySignResult = verifyFnGrd(signStrRtn.toString(), verifyCode, actItem);
                            if (verifySignResult) {
                                WriteBankLogLn2("验证签名成功");
                                if (transStateRet == null || "".equals(transStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易未知");
                                } else if ("2".equals(transStateRet) || "5".equals(transStateRet)) { //已退款也映射为支付成功了
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易成功");
                                    fillReturnData(retAts, tmpBkReader);
                                    //支付状态
                                    retAts.retHashMap.put("TransState", "2");
                                    /*retAts.retHashMap.put("Amount", tmpBkReader.getFirstText("/Root/TransResponse/Amount"));//交易实付金额（元，精确到小数两位）
                                    retAts.retHashMap.put("TransState", tmpBkReader.getFirstText("/Root/TransResponse/TransState"));//支付状态
                                    retAts.retHashMap.put("TransInfoCode", tmpBkReader.getFirstText("/Root/TransResponse/TransInfoCode"));//交易返回码
                                    retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/TransInfo"));//返回码对应的详细文字描述
                                    retAts.retHashMap.put("TransTime", tmpBkReader.getFirstText("/Root/TransResponse/TransTime"));//交易成功时间
                                    String tmpCustBankCode = tmpBkReader.getFirstText("/Root/TransResponse/CustBankCode");

                                    String bankCode = getBankConfig().getMapValueByKey("corBankCodeMapping", tmpCustBankCode);
                                    if (StringUtils.isNotEmpty(bankCode)) {
                                        tmpCustBankCode = bankCode;
                                    }

                                    retAts.retHashMap.put("CustBankCode", tmpCustBankCode);//交易银行代码
                                    retAts.retHashMap.put("CustAccount", tmpBkReader.getFirstText("/Root/TransResponse/CustAccount"));//缴费账户
                                    retAts.retHashMap.put("CustName", tmpBkReader.getFirstText("/Root/TransResponse/CustName"));//缴费账户对应姓名
                                    retAts.retHashMap.put("CertType", tmpBkReader.getFirstText("/Root/TransResponse/CertType"));//证件类型枚举
                                    retAts.retHashMap.put("CertNum", tmpBkReader.getFirstText("/Root/TransResponse/CertNum"));//缴费账户对应证件号
                                    retAts.retHashMap.put("PhoneNum", tmpBkReader.getFirstText("/Root/TransResponse/PhoneNum"));//手机号
                                    //第三方订单号
                                    retAts.retHashMap.put("OutTransactionId", tmpBkReader.getFirstText("/Root/TransResponse/OutTransactionId"));*/
                                } else if ("3".equals(transStateRet)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易失败");
                                    fillReturnData(retAts, tmpBkReader);
                                    /*retAts.retHashMap.put("Amount", tmpBkReader.getFirstText("/Root/TransResponse/Amount"));//交易实付金额（元，精确到小数两位）
                                    retAts.retHashMap.put("TransState", tmpBkReader.getFirstText("/Root/TransResponse/TransState"));//支付状态
                                    retAts.retHashMap.put("TransInfoCode", tmpBkReader.getFirstText("/Root/TransResponse/TransInfoCode"));//交易返回码
                                    retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/TransInfo"));//返回码对应的详细文字描述*/
                                } else if ("4".equals(transStateRet)) {  //未知
                                    fillReturnData(retAts, tmpBkReader);
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", tmpBkReader.getFirstText("/Root/TransResponse/TransInfo"));
                                    retAts.retHashMap.put("Amount", tmpBkReader.getFirstText("/Root/TransResponse/Amount"));//交易实付金额（元，精确到小数两位）
                                    retAts.retHashMap.put("TransState", tmpBkReader.getFirstText("/Root/TransResponse/TransState"));//支付状态
                                    retAts.retHashMap.put("TransInfoCode", tmpBkReader.getFirstText("/Root/TransResponse/TransInfoCode"));//交易返回码
                                    retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/TransInfo"));//返回码对应的详细文字描述
                                } else {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", "交易失败,渠道返回非法，值为：" + transStateRet);
                                }
                            } else {
                                retAts.retHashMap.put("RespCode", "0");
                                retAts.retHashMap.put("RespInfo", "验证签名失败");
                            }
                        } else if ("-1".equals(respCode)) {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "交易未知,请稍后查询交易单状态");
                            WriteBankLogLn2("交易未知,请稍后查询交易单状态");
                        } else {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "融合付返回的Respode非法，值为" + respCode);
                            WriteBankLogLn2("返回的RespCode非法");
                        }
                    }
                }

            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    /**
     * POS 支付
     *
     * @param p_reqElse POS 支付请求对象
     * @return POS 支付支付结果
     */
    public RetAtsOtherElse posPay(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);

        retAts.retHashMap = new HashMap<String, String>();
        try {
            //
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                FnGrd01Header bankHeader = new FnGrd01Header();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //缴费单号
                String exchangeNo = "";
                if (p_reqElse.reqHashMap.containsKey("ExchangeNo")) {
                    exchangeNo = p_reqElse.reqHashMap.get("ExchangeNo");
                }
                //请求码
                String transSeqID = "";
                if (p_reqElse.reqHashMap.containsKey("TransSeqID")) {
                    transSeqID = p_reqElse.reqHashMap.get("TransSeqID");
                }
                //收款员编号
                String OperatorID = "";
                if (p_reqElse.reqHashMap.containsKey("OperatorID")) {
                    OperatorID = p_reqElse.reqHashMap.get("OperatorID");
                }
                //POS机类型
                String PosType = "";
                if (p_reqElse.reqHashMap.containsKey("PosType")) {
                    PosType = p_reqElse.reqHashMap.get("PosType");
                }
                //POS机编号
                String DeviceID = "";
                if (p_reqElse.reqHashMap.containsKey("DeviceID")) {
                    DeviceID = p_reqElse.reqHashMap.get("DeviceID");
                }
                //交易类型
                String OrderType = "";
                if (p_reqElse.reqHashMap.containsKey("OrderType")) {
                    OrderType = p_reqElse.reqHashMap.get("OrderType");
                }
                //金额
                String Amount = "";
                if (p_reqElse.reqHashMap.containsKey("Amount")) {
                    Amount = p_reqElse.reqHashMap.get("Amount");
                }
                //通知地址
                String noticeUrl = actItem.posNoticeUrl;
                //商品描述
                String goodDesc = "";
                if (p_reqElse.reqHashMap.containsKey("GoodDesc")) {
                    goodDesc = p_reqElse.reqHashMap.get("GoodDesc");
                }
                //商品名称
                String goodName = "";
                if (p_reqElse.reqHashMap.containsKey("GoodName")) {
                    goodName = p_reqElse.reqHashMap.get("GoodName");
                }
                //原交易凭证号
                String OldTrace = "";
                if (p_reqElse.reqHashMap.containsKey("OldTrace")) {
                    OldTrace = p_reqElse.reqHashMap.get("OldTrace");
                }
                //原交易授权号
                String OldAuthCode = "";
                if (p_reqElse.reqHashMap.containsKey("OldAuthCode")) {
                    OldAuthCode = p_reqElse.reqHashMap.get("OldAuthCode");
                }
                //原系统参考号
                String OldRefNum = "";
                if (p_reqElse.reqHashMap.containsKey("OldRefNum")) {
                    OldRefNum = p_reqElse.reqHashMap.get("OldRefNum");
                }
                //订单创建时间
                String orderTime = "";
                if (p_reqElse.reqHashMap.containsKey("orderTime")) {
                    orderTime = p_reqElse.reqHashMap.get("orderTime");
                }
                //订单超时时间
                String overTime = "";
                if (p_reqElse.reqHashMap.containsKey("OverTime")) {
                    overTime = p_reqElse.reqHashMap.get("OverTime");
                }
                //条码信息
                String QrInfo = "";
                if (p_reqElse.reqHashMap.containsKey("QrInfo")) {
                    QrInfo = p_reqElse.reqHashMap.get("QrInfo");
                }
                //扩展字段1
                String extent1 = "";
                if (p_reqElse.reqHashMap.containsKey("Extent1")) {
                    extent1 = p_reqElse.reqHashMap.get("Extent1");
                }
                //扩展字段2
                String extent2 = "";
                if (p_reqElse.reqHashMap.containsKey("Extent2")) {
                    extent2 = p_reqElse.reqHashMap.get("Extent2");
                }
                //订单编号（只有PosType为快钱智能POS：app交互才需填写）
                String orderId = "";
                if (p_reqElse.reqHashMap.containsKey("OrderId")) {
                    orderId = p_reqElse.reqHashMap.get("OrderId");
                }
                //门店编号
                String shopNum = "";
                if (p_reqElse.reqHashMap.containsKey("ShopNum")) {
                    shopNum = p_reqElse.reqHashMap.get("ShopNum");
                }
                //组织机构号
                String comCode = "";  //目前POS接口这个字段：组织机构号
                if (p_reqElse.reqHashMap.containsKey("ComCode")) {
                    comCode = p_reqElse.reqHashMap.get("ComCode");
                }
                if ("02".equals(OrderType)) {
                    if (StringUtils.isEmpty(OldTrace)) {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "撤销交易时,OldTrace不可为空");
                        WriteBankLogLn2("撤销交易时,OldTrace不可为空");
                        return retAts;
                    }
                    if (StringUtils.isEmpty(OldAuthCode)) {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "撤销交易时,OldAuthCode不可为空");
                        WriteBankLogLn2("撤销交易时,OldAuthCode不可为空");
                        return retAts;
                    }
                    if (StringUtils.isEmpty(OldRefNum)) {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "撤销交易时,OldRefNum不可为空");
                        WriteBankLogLn2("撤销交易时,OldRefNum不可为空");
                        return retAts;
                    }
                }

                // 获取签名字符串:企业编号_交易流水号_订单编号_组织结构号_门店编号_收款员编号_POS类型_POS编号_交易类型_金额_通知地址
                StringBuilder signStr = new StringBuilder();
                signStr.append(enterpriseNum).append("_");
                signStr.append(exchangeNo).append("_");
                signStr.append(orderId).append("_");
                signStr.append(comCode).append("_");
                signStr.append(shopNum).append("_");
                signStr.append(OperatorID).append("_");
                signStr.append(PosType).append("_");
                signStr.append(DeviceID).append("_");
                signStr.append(OrderType).append("_");
                signStr.append(Amount).append("_");
                signStr.append(noticeUrl);
                //签名 签名验签原始数据组装：将关键字段使用 “_”即下划线进行连接，如果该字段值为空，下划线不能省略，如果该字段不存在，则省略。
                //意思是当一个空值时，两个“_”连在一起(现在在发往dsp前处理掉）
                //String signature = signFnGrd(actItem, signStr.toString().replace("null",""));
                WriteBankLogLn2("签名数据：" + signStr.toString());
                String signature = signFnGrd(actItem, signStr.toString());

                XmlTextWriter xmlWriter = new XmlTextWriter();
                xmlWriter.writeStartElement("Root");
                xmlWriter.writeStartElement("Head");
                xmlWriter.writeElementString("EnterpriseNum", enterpriseNum);
                xmlWriter.writeElementString("CommandCode", "70001");
                xmlWriter.writeElementString("TransSeqID", transSeqID);
                xmlWriter.writeElementString("VerifyCode", signature);
                xmlWriter.writeEndElement();
                xmlWriter.writeStartElement("TransRequest");
                xmlWriter.writeElementString("ReqNo", exchangeNo);
                xmlWriter.writeElementString("OrderId", orderId);
                xmlWriter.writeElementString("ComCode", comCode);
                xmlWriter.writeElementString("ShopNum", shopNum);
                xmlWriter.writeElementString("OperatorID", OperatorID);
                xmlWriter.writeElementString("PosType", PosType);
                xmlWriter.writeElementString("PosID", DeviceID);
                xmlWriter.writeElementString("TransType", OrderType);
                xmlWriter.writeElementString("Amount", Amount);
                xmlWriter.writeElementString("NoticeUrl", noticeUrl);
                xmlWriter.writeElementString("GoodDesc", goodDesc);
                xmlWriter.writeElementString("GoodName", goodName);
                xmlWriter.writeElementString("OldTrace", OldTrace);
                xmlWriter.writeElementString("OldAuthCode", OldAuthCode);
                xmlWriter.writeElementString("OldRefNum", OldRefNum);
                xmlWriter.writeElementString("OrderTime", orderTime);
                xmlWriter.writeElementString("OverTime", overTime);
                xmlWriter.writeElementString("QrInfo", QrInfo);
                xmlWriter.writeElementString("MchId", merchantId);
                xmlWriter.writeElementString("Extent1", extent1);
                xmlWriter.writeElementString("Extent2", extent2);
                xmlWriter.writeEndDocument();

                String reqSendData = getReqSendData(enterpriseNum, xmlWriter.toXmlString(), "GBK");

                // 服务地址
                String url = bankFront.getUrl("posPayOrderSubmit");
                if (StringHelper.isNullOrEmpty(url)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "POS支付服务地址为空,请检查BankFront.xml相关配置!");
                    return retAts;
                }
                String tmpRetStr = sendUnifiedToBank(reqSendData, url);
                //解密获得的返回参数
                String respData = this.getRespPostData(tmpRetStr, "GBK", "");
                //解析返回的xml报文
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(respData, tmpSbMsg);
                if (tmpBkReader != null) {
                    //判断交易的支付状态
                    String respCode = tmpBkReader.getFirstText("/Root/Head/RespCode");
                    //头部 RespCode 大于等于0，存在业务报文，且 AcceptCode 值为 0，判定为支付中
                    //头部 RespCode 大于等于0，存在业务报文，且 AcceptCode 值为 非0，判定为交易失败
                    //头部 RespCode 小于0，判定为交易未知
                    if (respCode == null || "".equals(respCode)) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "渠道返回的Respode为空");
                        WriteBankLogLn2("渠道返回的RespCode为空");
                    } else {
                        //RespCode 为 -1的时候不验签，RespCode 为 0的时候验签
                        if (!"-1".equals(respCode)) {
                            //验证返回报文中的签名信息--企业编号_请求流水号_订单编号_受理状态
                            String enterpriseNumRet = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                            String verifyCode = tmpBkReader.getFirstText("/Root/Head/VerifyCode");
                            String reqNoRet = tmpBkReader.getFirstText("/Root/TransResponse/ReqNo");
                            String AcceptCode = tmpBkReader.getFirstText("/Root/TransResponse/AcceptCode");
                            String orderIdRet = tmpBkReader.getFirstText("/Root/TransResponse/OrderId");

                            StringBuilder signStrRtn = new StringBuilder();
                            signStrRtn.append(enterpriseNumRet).append("_");
                            signStrRtn.append(reqNoRet).append("_");
                            signStrRtn.append(orderIdRet).append("_");//订单编号
                            signStrRtn.append(AcceptCode);

                            // 执行验签
                            WriteBankLogLn2("验签数据：" + signStrRtn.toString());
                            boolean verifySignResult = verifyFnGrd(signStrRtn.toString(), verifyCode, actItem);
                            if (verifySignResult) {
                                WriteBankLogLn2("验证签名成功");
                                if ("0".equals(AcceptCode)) {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", tmpBkReader.getFirstText("/Root/TransResponse/AcceptMessage"));
                                    retAts.retHashMap.put("TransState", "4");//支付状态
                                    retAts.retHashMap.put("TransInfoCode", "");//交易返回码
                                    retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/AcceptMessage"));//返回码对应的详细文字描述
                                    return retAts;
                                } else {
                                    retAts.retHashMap.put("RespCode", "0");
                                    retAts.retHashMap.put("RespInfo", tmpBkReader.getFirstText("/Root/TransResponse/AcceptMessage"));
                                    retAts.retHashMap.put("TransState", "3");//支付状态
                                    retAts.retHashMap.put("TransInfoCode", "");//交易返回码
                                    retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/AcceptMessage"));
                                    return retAts;
                                }
                            } else {
                                retAts.retHashMap.put("RespCode", "0");
                                retAts.retHashMap.put("RespInfo", "验证签名失败");
                                retAts.retHashMap.put("TransState", "3");//支付状态
                                retAts.retHashMap.put("TransInfoCode", "");//交易返回码
                                retAts.retHashMap.put("TransInfo", tmpBkReader.getFirstText("/Root/TransResponse/AcceptMessage"));
                                return retAts;
                            }
                        } else {
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("RespInfo", "交易未知,请稍后查询交易单状态");
                            retAts.retHashMap.put("TransState", "4");//支付状态
                            retAts.retHashMap.put("TransInfoCode", "");//交易返回码
                            retAts.retHashMap.put("TransInfo", "交易未知,请稍后查询交易单状态");
                            WriteBankLogLn2("交易未知,请稍后查询交易单状态");
                            return retAts;
                        }
                    }
                }

            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                return retAts;
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", "交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
            retAts.retHashMap.put("TransState", "4");//支付状态
            retAts.retHashMap.put("TransInfoCode", "");//交易返回码
            retAts.retHashMap.put("TransInfo", "交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
            return retAts;
        }
        return retAts;
    }

    private String getSignStr(ActSetItem actItem, String enterpriseNum, String reqNo, String authCode, String custName,
                              String certNum, String amount, String comCode) throws InvalidKeyException, SignatureException, Exception {
        StringBuilder signStr = new StringBuilder();
        signStr.append(enterpriseNum).append("_");
        signStr.append(reqNo).append("_");
        signStr.append(comCode).append("_");
        signStr.append(authCode).append("_");
        signStr.append(custName).append("_");
        signStr.append(certNum).append("_");
        signStr.append(amount);
        //签名
        return signFnGrd(actItem, signStr.toString());
    }

    /**
     * 远程付后台通知验签
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse verifyBackNoticeSignFnGrd(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                //请求流水号
                String reqNo = "";
                if (p_reqElse.reqHashMap.containsKey("ReqNo")) {
                    reqNo = p_reqElse.reqHashMap.get("ReqNo");
                }
                //见费出单系统状态
                String verifyCode = "";
                if (p_reqElse.reqHashMap.containsKey("VerifyCode")) {
                    verifyCode = p_reqElse.reqHashMap.get("VerifyCode");
                }
                //金额
                String amount = "";
                if (p_reqElse.reqHashMap.containsKey("Amount")) {
                    amount = p_reqElse.reqHashMap.get("Amount");
                }
                //交易状态
                String transState = "";
                if (p_reqElse.reqHashMap.containsKey("TransState")) {
                    transState = p_reqElse.reqHashMap.get("TransState");
                }

                StringBuilder signStr = new StringBuilder();
                if ("FGNATIVE04".equals(p_reqElse.reqHeader.commandCode)) {
                    //region  商户被扫
                    //缴费通知单号
                    String exchangeNo = "";
                    if (p_reqElse.reqHashMap.containsKey("ExchangeNo")) {
                        exchangeNo = p_reqElse.reqHashMap.get("ExchangeNo");
                    }

                    //见费出单系统状态
                    String feedbackState = "";
                    if (p_reqElse.reqHashMap.containsKey("FeedbackState")) {
                        feedbackState = p_reqElse.reqHashMap.get("FeedbackState");
                    }
                    //商户号（这里的商户号是由融汇通过后台通知回传的参数，用于参与签名）
                    String merchantIdsigned = "";
                    if (p_reqElse.reqHashMap.containsKey("MerchantId")) {
                        merchantIdsigned = p_reqElse.reqHashMap.get("MerchantId");
                    }
                    // 获取签名字符串--企业编号_请求流水号_缴费单号_金额_交易状态_见费出单状态_商户号
                    signStr.append(enterpriseNum).append("_");
                    signStr.append(reqNo).append("_");
                    signStr.append(exchangeNo).append("_");
                    signStr.append(amount).append("_");
                    signStr.append(transState).append("_");
                    //如果商户号为空，则不参与验签
                    if ("".equals(merchantIdsigned)) {
                        signStr.append(feedbackState);
                    } else {
                        signStr.append(feedbackState).append("_");
                        signStr.append(merchantIdsigned);
                    }
                    //endregion
                } else if ("POS01".equals(p_reqElse.reqHeader.commandCode)) {
                    //region 传统POS刷卡通知
                    //订单编号
                    String orderId = "";
                    if (p_reqElse.reqHashMap.containsKey("OrderId")) {
                        orderId = p_reqElse.reqHashMap.get("OrderId");
                    }
                    //门店编号
                    String shopNum = "";
                    if (p_reqElse.reqHashMap.containsKey("ShopNum")) {
                        shopNum = p_reqElse.reqHashMap.get("ShopNum");
                    }
                    //收款员编号
                    String operatorID = "";
                    if (p_reqElse.reqHashMap.containsKey("OperatorID")) {
                        operatorID = p_reqElse.reqHashMap.get("OperatorID");
                    }
                    //商户 POS 产商类型
                    String posType = "";
                    if (p_reqElse.reqHashMap.containsKey("PosType")) {
                        posType = p_reqElse.reqHashMap.get("PosType");
                    }
                    //POS机编号
                    String posID = "";
                    if (p_reqElse.reqHashMap.containsKey("PosID")) {
                        posID = p_reqElse.reqHashMap.get("PosID");
                    }
                    //交易类型
                    String transType = "";
                    if (p_reqElse.reqHashMap.containsKey("OrderType")) {
                        transType = p_reqElse.reqHashMap.get("OrderType");
                    }
                    //银行卡号
                    String bankCardNo = "";
                    if (p_reqElse.reqHashMap.containsKey("BankCardNo")) {
                        bankCardNo = p_reqElse.reqHashMap.get("BankCardNo");
                    }
                    //企业编号_交易流水号_订单号_门店编号_收款员编号_POS类型_POS编号_交易类型_金额_交易状态_银行卡号
                    signStr.append(enterpriseNum).append("_");
                    signStr.append(reqNo).append("_");
                    signStr.append(orderId).append("_");
                    signStr.append(shopNum).append("_");
                    signStr.append(operatorID).append("_");
                    signStr.append(posType).append("_");
                    signStr.append(posID).append("_");
                    signStr.append(transType).append("_");
                    signStr.append(amount).append("_");
                    signStr.append(transState).append("_");
                    signStr.append(bankCardNo);
                    //endregion
                } else if ("REFUNDAPPLY".equals(p_reqElse.reqHeader.commandCode)) {
                    //组织机构号
                    String comCode = "";
                    if (p_reqElse.reqHashMap.containsKey("ComCode")) {
                        comCode = p_reqElse.reqHashMap.get("ComCode");
                    }
                    //退款方式
                    String refundChannel = "";
                    if (p_reqElse.reqHashMap.containsKey("RefundChannel")) {
                        refundChannel = p_reqElse.reqHashMap.get("RefundChannel");
                    }
                    //退款单号
                    String refundNo = "";
                    if (p_reqElse.reqHashMap.containsKey("RefundNo")) {
                        refundNo = p_reqElse.reqHashMap.get("RefundNo");
                    }
                    //退款金额
                    String refundFee = "";
                    if (p_reqElse.reqHashMap.containsKey("RefundFee")) {
                        refundFee = p_reqElse.reqHashMap.get("RefundFee");
                    }
                    //退款状态：2-成功 3-失败
                    String refundState = "";
                    if (p_reqElse.reqHashMap.containsKey("RefundState")) {
                        refundState = p_reqElse.reqHashMap.get("RefundState");
                    }
                    //企业编号_组织机构号_退款方式_交易流水_退款单号_退款金额_退款状态
                    //组织机构号值取商户号值
                    signStr.append(enterpriseNum).append("_");
                    signStr.append(comCode).append("_");
                    signStr.append(refundChannel).append("_");
                    signStr.append(reqNo).append("_");
                    signStr.append(refundNo).append("_");
                    signStr.append(refundFee).append("_");
                    signStr.append(refundState);
                }
                boolean verifySignResult = verifyFnGrd(signStr.toString(), verifyCode, actItem);
                if (verifySignResult) {
                    WriteBankLogLn2("后台通知验证签名成功");
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验证签名成功");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验证签名失败");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    public RetAtsOtherElse verifyPosQuery(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失'ReqMsg'");
                return retAts;
            }

            // 1、解密融汇保单信息查询请求数据
            String decryptReqMsg = decryptByTripleDES(plain);
            WriteBankLogLn2("解密后原文信息为:\r\n" + decryptReqMsg);

            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(decryptReqMsg, tmpSbMsg);

            if (tmpBkReader != null) {
                String merchantId = tmpBkReader.getFirstText("/Root/TransRequest/MerchantId");
                ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
                if (actItem != null) {
                    // 2、验签
                    String sign = tmpBkReader.getFirstText("/Root/Head/VerifyCode");

                    // 签名字段：缴费通知单号_身份识别号（多个则多个间用下划线分割）_商户号
                    String askNumber = tmpBkReader.getFirstText("/Root/TransRequest/ExchangeNo");

                    String signData = askNumber + "_" + merchantId;

                    boolean verifySignResult = verifyFnGrd(signData, sign, actItem);
                    if (verifySignResult) {
                        // 3、验签通过后组返回S3数据
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名成功");

                        JSONObject result = new JSONObject();
                        result.put("Rdseq", askNumber);
                        result.put("IsRefund", "false");
                        result.put("ReserveField", decryptReqMsg);

                        retAts.retHashMap.put("Result", result.toJSONString());
                    } else {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "验签失败!");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "解析XML失败!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse signPosQuery(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
                return retAts;
            }

            JSONObject reqJson = JSONObject.parseObject(plain);

            String reserveField = reqJson.getString("ReserveField");
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(reserveField, tmpSbMsg);

            if (tmpBkReader != null) {
                String merchantId = tmpBkReader.getFirstText("/Root/TransRequest/MerchantId");
                ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
                if (actItem != null) {
                    String askNumber = reqJson.getString("Rdseq");
                    String amount = reqJson.getString("Amount");

                    String signData = "1;" + askNumber + "_" + amount + "_1";

                    String sign = signFnGrd(actItem, signData);

                    XmlTextWriter xmlWriter = new XmlTextWriter();
                    xmlWriter.writeStartElement("Root");

                    xmlWriter.writeStartElement("Head");
                    xmlWriter.writeElementString("EnterpriseNum", tmpBkReader.getFirstText("/Root/TransRequest/EnterpriseNum"));
                    xmlWriter.writeElementString("CommandCode", tmpBkReader.getFirstText("/Root/TransRequest/CommandCode"));
                    xmlWriter.writeElementString("TransSeqID", tmpBkReader.getFirstText("/Root/TransRequest/TransSeqID"));
                    xmlWriter.writeElementString("VerifyCode", sign);
                    xmlWriter.writeElementString("RespCode", "0");
                    xmlWriter.writeElementString("RespInfo", "");

                    xmlWriter.writeStartElement("TransResponse");
                    xmlWriter.writeElementString("TotalNum", "1");

                    xmlWriter.writeStartElement("OrderDetail");
                    xmlWriter.writeElementString("ReqNo", "");
                    xmlWriter.writeElementString("ExchangeNo", reqJson.getString("Rdseq"));
                    xmlWriter.writeElementString("IdentityId", "");
                    xmlWriter.writeElementString("CustName", reqJson.getString("BankAccountName"));
                    xmlWriter.writeElementString("CertType", "0");
                    xmlWriter.writeElementString("CertNum", reqJson.getString("CertNumber"));
                    xmlWriter.writeElementString("PhoneNum", "0");
                    xmlWriter.writeElementString("GoodsTitle", reqJson.getString("Description"));
                    xmlWriter.writeElementString("GoodsType", "1");// 待解决
                    xmlWriter.writeElementString("Amount", reqJson.getString("Amount"));
                    xmlWriter.writeElementString("DiscountAmount", "0.00");
                    xmlWriter.writeElementString("OrderInfo", reqJson.getString("Memo"));// 待解决
                    xmlWriter.writeElementString("CreateTime", Format.DateTimeFormat.format(new Date()));
                    xmlWriter.writeElementString("InvalidTime", Format.DateTimeFormat.format(new Date()));// 待解决
                    xmlWriter.writeElementString("OrderStatus", "1");// 待解决
                    xmlWriter.writeElementString("IsCheckIdentity", "0");
                    xmlWriter.writeElementString("Extern1", "");
                    xmlWriter.writeElementString("Extern2", "");
                    xmlWriter.writeElementString("CertiNo", "");
                    xmlWriter.writeEndElement();
                    xmlWriter.writeEndDocument();

                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "");
                    retAts.retHashMap.put("Result", xmlWriter.toXmlString());
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "解析XML失败!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse verifyPosNotify(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失'ReqMsg'");
                return retAts;
            }

            // 1、解密融汇保单信息查询请求数据
            String decryptReqMsg = decryptByTripleDES(plain);
            WriteBankLogLn2("解密后原文信息为:\r\n" + decryptReqMsg);

            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(decryptReqMsg, tmpSbMsg);

            if (tmpBkReader != null) {
                String merchantId = tmpBkReader.getFirstText("/Root/TransRequest/MerchantId");
                ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
                if (actItem != null) {
                    // 2、验签
                    String sign = tmpBkReader.getFirstText("/Root/Head/VerifyCode");

                    // 企业编号_请求流水号_缴费单号_金额_交易状态_见费出单状态_商户号
                    String enterpriseNum = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                    String reqNo = tmpBkReader.getFirstText("/Root/TransRequest/ReqNo");
                    String askNumber = tmpBkReader.getFirstText("/Root/TransRequest/ExchangeNo");
                    String amount = tmpBkReader.getFirstText("/Root/TransRequest/Amount");
                    String status = tmpBkReader.getFirstText("/Root/TransRequest/TransState");
                    String feedbackState = tmpBkReader.getFirstText("/Root/TransRequest/FeedbackState");

                    String signData = enterpriseNum + "_" + reqNo + "_" + askNumber + "_" + amount + "_" + status + "_" + feedbackState + "_" + merchantId;

                    boolean verifySignResult = verifyFnGrd(signData, sign, actItem);
                    if (verifySignResult) {
                        // 3、验签通过后组返回S3数据
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名成功");

                        JSONObject result = new JSONObject();
                        result.put("Rdseq", askNumber);
                        result.put("IsRefund", "false");
                        result.put("ReserveField", decryptReqMsg);
                        result.put("PayState", status);
                        result.put("PayInfoCode", tmpBkReader.getFirstText("/Root/TransRequest/TransInfoCode"));
                        result.put("PayInfo", tmpBkReader.getFirstText("/Root/TransRequest/TransInfo"));
                        result.put("Amount", amount);
                        result.put("Asknumber", reqNo);
                        result.put("Abstracts", "");
                        String transTime = tmpBkReader.getFirstText("/Root/TransRequest/TransTime");
                        result.put("PayMadeDate", Format.DateTime14Format.format(new DateFormat2("yyyy/MM/dd HH:mm:ss").parse(transTime)));
                        result.put("OppBankAccount", tmpBkReader.getFirstText("/Root/TransRequest/CustAccount"));
                        result.put("OppBankCode", "");
                        result.put("Reserved01", "");
                        result.put("Reserved02", "");

                        retAts.retHashMap.put("Result", result.toJSONString());
                    } else {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "验签失败!");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "解析XML失败!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    public RetAtsOtherElse signPosNotify(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();

        try {
            String plain = "";
            if (p_reqElse.reqHashMap.containsKey("ReqMsg")) {
                plain = StringEscapeUtils.unescapeHtml(p_reqElse.reqHashMap.get("ReqMsg"));
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "缺失原始串'ReqMsg'");
                return retAts;
            }

            JSONObject reqJson = JSONObject.parseObject(plain);

            String reserveField = reqJson.getString("ReserveField");
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(reserveField, tmpSbMsg);

            if (tmpBkReader != null) {
                String merchantId = tmpBkReader.getFirstText("/Root/TransRequest/MerchantId");
                ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "pos");
                if (actItem != null) {
                    // 企业编号_状态_保单号
                    String enterpriseNum = tmpBkReader.getFirstText("/Root/Head/EnterpriseNum");
                    String status = tmpBkReader.getFirstText("/Root/TransRequest/TransState");
                    String certiNo = tmpBkReader.getFirstText("/Root/TransRequest/CertiNo");
                    String signData = enterpriseNum + "_" + status + "_" + certiNo;
                    String sign = signFnGrd(actItem, signData);

                    XmlTextWriter xmlWriter = new XmlTextWriter();
                    xmlWriter.writeStartElement("Root");

                    xmlWriter.writeStartElement("Head");
                    xmlWriter.writeElementString("EnterpriseNum", tmpBkReader.getFirstText("/Root/TransRequest/EnterpriseNum"));
                    xmlWriter.writeElementString("CommandCode", tmpBkReader.getFirstText("/Root/TransRequest/CommandCode"));
                    xmlWriter.writeElementString("TransSeqID", tmpBkReader.getFirstText("/Root/TransRequest/TransSeqID"));
                    xmlWriter.writeElementString("VerifyCode", sign);
                    xmlWriter.writeElementString("RespCode", "0");
                    xmlWriter.writeElementString("RespInfo", "");

                    xmlWriter.writeStartElement("TransResponse");
                    xmlWriter.writeElementString("State", status); // 2 成功，3失败
                    xmlWriter.writeElementString("InfoCode", tmpBkReader.getFirstText("/Root/TransRequest/TransInfoCode"));
                    xmlWriter.writeElementString("Info", tmpBkReader.getFirstText("/Root/TransRequest/TransInfo"));
                    xmlWriter.writeElementString("PolicyCode", "");
                    xmlWriter.writeEndElement();
                    xmlWriter.writeEndDocument();

                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "");
                    retAts.retHashMap.put("Result", xmlWriter.toXmlString());
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "未找到账号:" + merchantId + "商户配置信息!");
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "解析XML失败!");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", ex.getMessage());
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    /**
     * 微信公众号（小程序）支付
     *
     * @param p_reqElse
     * @return
     */
    private RetAtsOtherElse getJSAPIUrl(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String openId = p_reqElse.reqHashMap.get("OpenId");
            String merchantId = p_reqElse.reqHashMap.get("MchId");
            String appId = p_reqElse.reqHashMap.get("AppId");
            String reqNo = p_reqElse.reqHashMap.get("ReqNo");

            //是否小程序支付，1：是，0：不是，默认0
            String isMiniPg = "";
            if (p_reqElse.reqHashMap.containsKey("IsMiniPg")) {
                isMiniPg = p_reqElse.reqHashMap.get("IsMiniPg");
            }
            //开始时间     yyyyMMddHHmmss
            String orderTime = "";
            if (p_reqElse.reqHashMap.containsKey("OrderTime")) {
                orderTime = p_reqElse.reqHashMap.get("OrderTime");
            }
            //到期时间     yyyyMMddHHmmss
            String expireTime = "";
            if (p_reqElse.reqHashMap.containsKey("ExpireTime")) {
                expireTime = p_reqElse.reqHashMap.get("ExpireTime");
            }
            //附加信息
            String memo = "";
            if (p_reqElse.reqHashMap.containsKey("Memo")) {
                memo = p_reqElse.reqHashMap.get("Memo");
            }
            //证件号
            String certNum = "";
            if (p_reqElse.reqHashMap.containsKey("CertNum")) {
                certNum = p_reqElse.reqHashMap.get("CertNum");
            }
            //真实姓名
            String custName = "";
            if (p_reqElse.reqHashMap.containsKey("CustName")) {
                custName = p_reqElse.reqHashMap.get("CustName");
            }
            //手机号
            String phoneNum = "";
            if (p_reqElse.reqHashMap.containsKey("PhoneNum")) {
                phoneNum = p_reqElse.reqHashMap.get("PhoneNum");
            }
            String succBackUrl = "";
            if (p_reqElse.reqHashMap.containsKey("CallBackUrl")) {
                succBackUrl = p_reqElse.reqHashMap.get("CallBackUrl");
            }
            String failBackUrl = "";
            if (p_reqElse.reqHashMap.containsKey("ReSendUrl")) {
                failBackUrl = p_reqElse.reqHashMap.get("ReSendUrl");
            }
            String isRaw = "";
            if (p_reqElse.reqHashMap.containsKey("IsRaw")) {
                isRaw = p_reqElse.reqHashMap.get("IsRaw");
            }
            String organizationId = "";
            if (p_reqElse.reqHashMap.containsKey("OrganizationId")) {
                organizationId = p_reqElse.reqHashMap.get("OrganizationId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "appId", "unifiedorder");
            if (actItem != null) {

                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", merchantId);
                mapParams.put("AppId", appId);
                mapParams.put("OutTradeNo", reqNo);
                mapParams.put("Body", XmlHelper.encode(p_reqElse.reqHashMap.get("GoodDesc")));//商品描述
                mapParams.put("TotalFee", p_reqElse.reqHashMap.get("Amount"));//分
                mapParams.put("MchCreateIp", actItem.createIP);//订单生成的机器ip
                //mapParams.put("NotifyUrl",p_reqElse.reqHashMap.get("NoticeUrl"));
                mapParams.put("NotifyUrl", actItem.webAPINotifyUrl);
                mapParams.put("OpenId", openId);
                mapParams.put("CallFlag", "00");//00：不回调，01：调用见费，默认为00，只做正常结果通知
                mapParams.put("NonceStr", get_nonce_str());

                if ("0".equals(isMiniPg)) {//融汇的代码逻辑是为公众号时这个字段为空或“0”；没按文档写为“0”
                    mapParams.put("IsMiniPg", "");
                }
                mapParams.put("SuccBackUrl", succBackUrl);//支付成功跳转地址（非原生支付用）
                mapParams.put("FailBackUrl", failBackUrl);//支付失败跳转地址（非原生支付用）
                mapParams.put("Attach", memo);
                mapParams.put("DeviceInfo", "");//终端IP，可为空，也可以传易企收的订单生成的机器IPTERMINALID
                mapParams.put("LimitCreditPay", getBankConfig().getValueAsString("LimitCreditPay"));
                mapParams.put("GoodsTag", "");
                mapParams.put("OrganizationId", organizationId);
                mapParams.put("TimeStart", orderTime);
                mapParams.put("TimeExpire", expireTime);
                mapParams.put("CertType", convertCertTypeToBank(p_reqElse.reqHashMap.get("CertType")));
                mapParams.put("CertNum", certNum);
                mapParams.put("CustName", custName);
                mapParams.put("PhoneNum", phoneNum);
                if ("0".equals(isMiniPg)) {
                    mapParams.put("IsRaw", "1");//是否原生，0：是，1：否，默认0，公众号支付用。
                }
                if (StringHelper.hasAnyChar(custName) || StringHelper.hasAnyChar(phoneNum) || StringHelper.hasAnyChar(certNum)) {
                    mapParams.put("IsCheckIdentity", "1");
                } else {
                    mapParams.put("IsCheckIdentity", "0");
                }
                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey);
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);

                String reqPostJson = getReqPostJson(mapParams);
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson);

                String serverUrl = "";
                if ("0".equals(isMiniPg)) {
                    serverUrl = bankFront.getUrl("jsapiWXOrder");//微信公众号支付请求地址
                } else {
                    serverUrl = bankFront.getUrl("jsapiWXMiniProgramPayOrder");//小程序支付请求地址
                }

                String temStr = sendUnifiedToBank(reqSendData, serverUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") == 0) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));

                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "成功");
                        retAts.retHashMap.put("EnterpriseNum", respJSONObj.getString("EnterpriseNum"));
                        retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                        retAts.retHashMap.put("OutTradeId", respJSONObj.getString("FGTradeNo"));//第三方订单号

                        if ("1".equals(isMiniPg) || "0".equals(isRaw)) {
                            JSONObject tmpPayInfo = JSONObject.parseObject(respJSONObj.getString("PayInfo"));
                            retAts.retHashMap.put("appId", tmpPayInfo.getString("appId"));
                            retAts.retHashMap.put("nonceStr", tmpPayInfo.getString("nonceStr"));
                            retAts.retHashMap.put("timeStamp", tmpPayInfo.getString("timeStamp"));
                            retAts.retHashMap.put("package", tmpPayInfo.getString("package"));
                            retAts.retHashMap.put("signType", tmpPayInfo.getString("signType"));
                            retAts.retHashMap.put("paySign", tmpPayInfo.getString("paySign"));
                            retAts.retHashMap.put("PayInfo", respJSONObj.getString("PayInfo"));
                        } else {  //微信公众号支付非原生支付
                            retAts.retHashMap.put("PayUrl", respJSONObj.getString("PayUrl"));
                        }
                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }

        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    /**
     * 来自webapi的结果通知
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse VerifyBackNoticeSignWebapi(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String returnMsg = "";
            if (p_reqElse.reqHashMap.containsKey("ReturnMsg")) {
                returnMsg = p_reqElse.reqHashMap.get("ReturnMsg");
            }
            String openId = "";
            if (p_reqElse.reqHashMap.containsKey("OpenId")) {
                openId = p_reqElse.reqHashMap.get("OpenId");
            }
            String isSubscribe = "";
            if (p_reqElse.reqHashMap.containsKey("IsSubscribe")) {
                isSubscribe = p_reqElse.reqHashMap.get("IsSubscribe");
            }
            String bankType = "";//银行类型，成功以外状态，该字段为空
            if (p_reqElse.reqHashMap.containsKey("BankType")) {
                bankType = p_reqElse.reqHashMap.get("BankType");
            }
            String bankBillNo = "";//银行订单号，若为微信支付则为空
            if (p_reqElse.reqHashMap.containsKey("BankBillNo")) {
                bankBillNo = p_reqElse.reqHashMap.get("BankBillNo");
            }
            String attach = "";//附加信息
            if (p_reqElse.reqHashMap.containsKey("Attach")) {
                attach = p_reqElse.reqHashMap.get("Attach");
            }
            String transaction_id = "";//微信订单号
            if (p_reqElse.reqHashMap.containsKey("Transaction_id")) {
                transaction_id = p_reqElse.reqHashMap.get("Transaction_id");
            }
            String endTime = "";//yyyyMMddHHmmss，成功以外状态，该字段为空
            if (p_reqElse.reqHashMap.containsKey("PayMadeDate")) {
                endTime = p_reqElse.reqHashMap.get("PayMadeDate");
            }
            String callResult = "";//调外部系统结果，0：成功，1：失败，2：未知，3：未调用，4：未知情况客户可以来查询
            if (p_reqElse.reqHashMap.containsKey("CallResult")) {
                callResult = p_reqElse.reqHashMap.get("CallResult");
            }
            String circPaymentNo = ""; //标识唯一保单的交易号，保信实名用
            if (p_reqElse.reqHashMap.containsKey("CircPaymentNo")) {
                circPaymentNo = p_reqElse.reqHashMap.get("CircPaymentNo");
            }
            String notifyStatus = ""; //微信通知保信结果，SUCCESS/FAIL
            if (p_reqElse.reqHashMap.containsKey("NotifyStatus")) {
                notifyStatus = p_reqElse.reqHashMap.get("NotifyStatus");
            }
            String merchantId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("Status", p_reqElse.reqHashMap.get("Status"));
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", merchantId);
                mapParams.put("NonceStr", p_reqElse.reqHashMap.get("NonceStr"));
                mapParams.put("OutTradeNo", p_reqElse.reqHashMap.get("OutTradeNo"));
                mapParams.put("TotalFee", p_reqElse.reqHashMap.get("Amount"));
                mapParams.put("FeeType", p_reqElse.reqHashMap.get("FeeType"));
                mapParams.put("FGTradeNo", p_reqElse.reqHashMap.get("OutTradeid"));//第三方订单号
                mapParams.put("TradeState", p_reqElse.reqHashMap.get("TradeState"));//SUCCESS—支付成功CLOSED—已关闭
                mapParams.put("Signature", p_reqElse.reqHashMap.get("Signature"));//签名，组装的时候会踢除的，先放着。

                mapParams.put("ReturnMsg", returnMsg);
                mapParams.put("OpenId", openId);
                mapParams.put("Attach", attach);
                mapParams.put("Transaction_id", transaction_id);
                mapParams.put("TimeEnd", endTime);
                mapParams.put("CallResult", callResult);
                //以下字段是微信部分返回的字段，当支付宝返回是为空，组装签名时会剔除
                mapParams.put("IsSubscribe", isSubscribe);
                mapParams.put("BankType", bankType);
                mapParams.put("BankBillNo", bankBillNo);
                mapParams.put("CircPaymentNo", circPaymentNo);
                mapParams.put("NotifyStatus", notifyStatus);
                String plainStr = getSignStr(mapParams, actItem.webAPISercretKey);

                boolean verifySignResult = verifySign(actItem, plainStr, p_reqElse.reqHashMap.get("Signature"));

                if (verifySignResult) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "验签通过");
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "验签失败");
                }

            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }

    /**
     * webapi 支付结果查询
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse QueryWebAPIPay(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }

            String exchangeNo = p_reqElse.reqHashMap.get("ExchangeNo");
            String outTradeId = p_reqElse.reqHashMap.get("OutTradeId");//保融订单号  第三方订单号

            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", actItem.merchantId);
                mapParams.put("OutTradeNo", exchangeNo);
                mapParams.put("FGTradeNo", outTradeId);
                mapParams.put("NonceStr", get_nonce_str());
                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey);
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);

                String reqPostJson = getReqPostJson(mapParams);
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson);

                String serveUrl = "";
                String commandCode = p_reqElse.reqHeader.commandCode;
                if ("JSAPI01".equals(commandCode) || "FGNATIVE01".equals(commandCode)) {
                    serveUrl = bankFront.getUrl("webapiQueryWXQRPay"); //微信查询地址
                } else if ("FGNATIVE02".equals(commandCode)) {
                    serveUrl = bankFront.getUrl("webapiAliPayQuery"); // 支付宝查询地址
                }

                String temStr = sendUnifiedToBank(reqSendData, serveUrl);

                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSON = JSON.parseObject(sourceData);
                if (respJSON.containsKey("Status") && respJSON.getIntValue("Status") == 0) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);

                    boolean flag = verifySign(actItem, toSignData, respJSON.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("TransInfo", respJSON.getString("ReturnMsg"));//该字段融汇返回为非必填
                        retAts.retHashMap.put("EnterpriseNum", respJSON.getString("EnterpriseNum"));
                        retAts.retHashMap.put("MchId", respJSON.getString("MchId"));

                        if ("SUCCESS".equals(respJSON.getString("TradeState"))) {
                            retAts.retHashMap.put("TransState", "2");//支付成功
                            retAts.retHashMap.put("TransInfoCode", "S0000");//成功
                            retAts.retHashMap.put("TransInfo", "交易成功");
                        } else if ("NOTPAY".equals(respJSON.getString("TradeState"))) {
                            retAts.retHashMap.put("TransState", "4");//未支付
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "未支付");
                        } else if ("REFUND".equals(respJSON.getString("TradeState"))) {
                            retAts.retHashMap.put("TransState", "2");//转入退款|| 已撤销
                            retAts.retHashMap.put("TransInfoCode", "S0000");//退票
                            retAts.retHashMap.put("TransInfo", "转入退款或已撤销");
                        } else if ("PAYERROR".equals(respJSON.getString("TradeState"))) {
                            retAts.retHashMap.put("TransState", "3");//支付失败(其他原因，如银行返回失败)
                            retAts.retHashMap.put("TransInfoCode", "E8001");
                            retAts.retHashMap.put("TransInfo", "支付失败");
                        } else if ("REVERSE".equals(respJSON.getString("TradeState"))) {
                            retAts.retHashMap.put("TransState", "12");//已撤销
                            retAts.retHashMap.put("TransInfoCode", "E8121");
                            retAts.retHashMap.put("TransInfo", "已撤销");
                        } else if ("CLOSED".equals(respJSON.getString("TradeState"))) {
                            retAts.retHashMap.put("TransState", "11");//已关闭
                            retAts.retHashMap.put("TransInfoCode", "E8031");
                            retAts.retHashMap.put("TransInfo", "已关闭");
                        } else {
                            retAts.retHashMap.put("TransState", "4"); // TODO: 其他可知的状态怎么处理,先置为处理中
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("TransInfo", "未知状态");
                            retAts.retHashMap.put("RespInfo", respJSON.getString("TradeState"));
                        }

                        if ("JSAPI01".equals(commandCode) || "FGNATIVE01".equals(commandCode)) { //webapi微信部分多返回两个字段
                            retAts.retHashMap.put("Appid", respJSON.getString("Appid"));
                            retAts.retHashMap.put("OpenId", respJSON.getString("OpenId"));
                        }
                        if ("FGNATIVE02".equals(commandCode)) { //webapi支付宝部分多返回4个金额字段
                            retAts.retHashMap.put("ReceiptAmount", respJSON.getString("ReceiptAmount")); //商户实收金额
                            retAts.retHashMap.put("BuyerPayAmount", respJSON.getString("BuyerPayAmount")); //买家实付金额
                            retAts.retHashMap.put("MdiscountAmount", respJSON.getString("MdiscountAmount")); //商家优惠金额
                            retAts.retHashMap.put("DiscountAmount", respJSON.getString("DiscountAmount")); //平台优惠金额
                        }
                        retAts.retHashMap.put("IsSubscribe", respJSON.getString("IsSubscribe"));

                        retAts.retHashMap.put("ExchangeNo", respJSON.getString("OutTradeNo"));//第三方订单号
                        retAts.retHashMap.put("OutTransactionId", respJSON.getString("FGTradeNo"));
                        retAts.retHashMap.put("TotalFee", respJSON.getString("TotalFee"));
                        retAts.retHashMap.put("FeeType", respJSON.getString("FeeType"));
                        retAts.retHashMap.put("BankType", respJSON.getString("BankType"));
                        String transTime = respJSON.getString("TimeEnd");
                        if (!StringHelper.isNullOrEmpty(transTime)) {
                            try {
                                Date transDateStr = new SimpleDateFormat("yyyyMMddHHmmss").parse(transTime);
                                String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transDateStr);
                                retAts.retHashMap.put("TransTime", dateStr);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        retAts.retHashMap.put("bankOrderNo", respJSON.getString("Transaction_id"));//微信订单号
                        retAts.retHashMap.put("Attach", respJSON.getString("Attach"));
                        retAts.retHashMap.put("BankBillNo", respJSON.getString("BankBillNo"));//银行订单号，若为微信支付则为空

                        retAts.retHashMap.put("CustBankCode", "");

                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSON.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }

        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    /**
     * webAPI 退款查询
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse queryWebAPIRefund(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                String commandCode = p_reqElse.reqHeader.commandCode;
                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", actItem.merchantId);
                mapParams.put("OutTradeNo", p_reqElse.reqHashMap.get("ReqNo"));
                mapParams.put("FGTradeNo", p_reqElse.reqHashMap.get("FGTradeNo"));
                mapParams.put("RefundNo", p_reqElse.reqHashMap.get("RefundNo"));
                mapParams.put("FGRefundNo", p_reqElse.reqHashMap.get("FGRefundNo")); //约定不填此字段,不过联调时富友渠道要填
                mapParams.put("NonceStr", get_nonce_str());
                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey);
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);

                // post请求数据
                String reqPostJson = getReqPostJson(mapParams);
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson);

                String url = bankFront.getUrl("webapiQRPayRefundQuery");
                if (StringHelper.isNullOrEmpty(url)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "JSAPI退款申请服务地址为空,请检查BankFront.xml相关配置!");
                    return retAts;
                }
                // 发融汇
                String temStr = sendUnifiedToBank(reqSendData, url);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") != -1) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);

                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("ReqNo", respJSONObj.getString("OutTradeNo"));
                        retAts.retHashMap.put("FGRefundNo", respJSONObj.getString("FGRefundNo"));//保融退款单号
                        retAts.retHashMap.put("MerchantId", respJSONObj.getString("MchId"));
                        String refundCount = respJSONObj.getString("RefundCount");
                        retAts.retHashMap.put("RefundCount", refundCount);//退款笔数
                        for (int n = 0; n < Integer.valueOf(refundCount); n++) {
                            retAts.retHashMap.put("RefundNo_" + n, respJSONObj.getString("RefundNo_" + n));
                            retAts.retHashMap.put("FGRefundNo_" + n, respJSONObj.getString("FGRefundNo_" + n));
                            retAts.retHashMap.put("RefundChannel_" + n, respJSONObj.getString("RefundChannel_" + n));
                            retAts.retHashMap.put("RefundFee_" + n, respJSONObj.getString("RefundFee_" + n));
                            if ("FGNATIVE02".equals(commandCode)) { //支付宝多返回4个，微信的尚未要求（返回为空），所以先过滤
                                retAts.retHashMap.put("RefundChargeAmount_" + n, respJSONObj.getString("RefundChargeAmount_" + n));
                                retAts.retHashMap.put("PresentRefundBuyerAmount_" + n, respJSONObj.getString("PresentRefundBuyerAmount_" + n));
                                retAts.retHashMap.put("PresentRefundDiscountAmount_" + n, respJSONObj.getString("PresentRefundDiscountAmount_" + n));
                                retAts.retHashMap.put("PresentRefundMdiscountAmount_" + n, respJSONObj.getString("PresentRefundMdiscountAmount_" + n));
                            }

                            String refundTime = respJSONObj.getString("RefundTime_" + n);
                            if (!StringHelper.isNullOrEmpty(refundTime)) {
                                try {
                                    Date transDateStr = new SimpleDateFormat("yyyyMMddHHmmss").parse(refundTime);
                                    String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transDateStr);
                                    retAts.retHashMap.put("RefundTime_" + n, dateStr);
                                } catch (ParseException e) {
                                    e.printStackTrace();
                                }
                            }

                            String refundStatus = respJSONObj.getString("RefundStatus_" + n);
                            if ("SUCCESS".equals(refundStatus)) {//退款成功
                                retAts.retHashMap.put("RefundStatus", "2");
                                retAts.retHashMap.put("RefundInfoCode", "S0000");
                                retAts.retHashMap.put("RespInfo", "退款成功");
                            } else if ("FAIL".equals(refundStatus) || "NOTSURE".equals(refundStatus) || "CHANGE".equals(refundStatus)) {
                                //退款失败；
                                // 未确定， 需要商户原退款单号重新发起；
                                //转入代发，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，资金回流到商户的现金帐号，需要商户人工干预，通过线下或者平台转账的方式进行退款。
                                retAts.retHashMap.put("RefundStatus", "3");
                                retAts.retHashMap.put("RefundInfoCode", "E8001");
                                retAts.retHashMap.put("RespInfo", "退款失败");
                            } else if ("PROCESSING".equals(refundStatus) || "NOTSURE".equals(refundStatus)) {//退款处理中 ||未确定，?需要商户原退款单号重新发起
                                retAts.retHashMap.put("RefundStatus", "4");
                                retAts.retHashMap.put("RefundInfoCode", "I4001");
                                retAts.retHashMap.put("RespInfo", "退款处理中");
                            } else {
                                retAts.retHashMap.put("RefundStatus", "4"); // TODO: 其他可知的状态怎么处理，先置为处理中
                                retAts.retHashMap.put("RefundInfoCode", "E8001");//未知
                                retAts.retHashMap.put("RespInfo", refundStatus);
                            }

                        }
                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }

    /**
     * WebAPI 退款
     *
     * @param p_reqElse
     * @return
     */
    public RetAtsOtherElse webAPIRefund(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String merchantId = "";
            if (p_reqElse.reqHashMap.containsKey("MchId")) {
                merchantId = p_reqElse.reqHashMap.get("MchId");
            }
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", merchantId, "", "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                //智慧门店用，内容是Json数组
                String detail = "";
                if (p_reqElse.reqHashMap.containsKey("GoodsDetail")) {
                    detail = p_reqElse.reqHashMap.get("GoodsDetail");
                }
                //门店编号，智慧门店用
                //20190530:支付宝条码支付请求、退款请求门店编号字段改为组织机构号
                String organizationId = "";
                if (p_reqElse.reqHashMap.containsKey("StoreId")) {
                    organizationId = p_reqElse.reqHashMap.get("StoreId");
                }
                //商户操作员编号，智慧门店用
                String operatorId = "";
                if (p_reqElse.reqHashMap.containsKey("OperatorId")) {
                    operatorId = p_reqElse.reqHashMap.get("OperatorId");
                }
                //商户机具终端编号
                String terminalId = "";
                if (p_reqElse.reqHashMap.containsKey("TerminalId")) {
                    terminalId = p_reqElse.reqHashMap.get("TerminalId");
                }
                String commandCode = p_reqElse.reqHeader.commandCode;
                JSONArray goodsDetailArray = new JSONArray();
                if (!"".equals(detail)) {
                    JSONArray jsonArray = JSONArray.parseArray(detail);
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject goods_detail_i = new JSONObject();
                        goods_detail_i.put("GoodsId", jsonArray.getJSONObject(i).getString("goods_id"));
                        goods_detail_i.put("GoodsName", jsonArray.getJSONObject(i).getString("goods_name"));
                        goods_detail_i.put("Quantity", jsonArray.getJSONObject(i).getString("quantity"));
                        String price = jsonArray.getJSONObject(i).getString("price");
                        BigDecimal priceNum = new BigDecimal(price);
                        Long longPrice = priceNum.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).longValue();
                        goods_detail_i.put("Price", longPrice);
                        goodsDetailArray.add(goods_detail_i);
                    }
                }
                String goodDetailStr = JSONObject.toJSONString(goodsDetailArray, SerializerFeature.DisableCircularReferenceDetect);
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", actItem.merchantId);
                mapParams.put("OutTradeNo", p_reqElse.reqHashMap.get("ReqNo"));
                mapParams.put("FGTradeNo", p_reqElse.reqHashMap.get("FGTradeNo"));
                mapParams.put("RefundNo", p_reqElse.reqHashMap.get("RefundNo"));
                mapParams.put("TotalFee", p_reqElse.reqHashMap.get("TotalFee"));
                mapParams.put("RefundFee", p_reqElse.reqHashMap.get("RefundFee"));
                mapParams.put("RefundChannel", "ORIGINAL"); /* ORIGINAL-原路退款，默认 */
                mapParams.put("GoodsDetail", goodDetailStr);
                mapParams.put("OrganizationId", organizationId);
                mapParams.put("OperatorId", operatorId);
                mapParams.put("TerminalId", terminalId);
                mapParams.put("NonceStr", get_nonce_str());

                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey);
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);
                // post请求数据
                String reqPostJson = getReqPostJson(mapParams);
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson);

                String url = bankFront.getUrl("webapiQRPayRefundSubmit");
                if (StringHelper.isNullOrEmpty(url)) {
                    retAts.retHashMap.put("RespCode", "0");
                    retAts.retHashMap.put("RespInfo", "JSAPI退款申请服务地址为空,请检查BankFront.xml相关配置!");
                    return retAts;
                }
                // 发融汇
                String temStr = sendUnifiedToBank(reqSendData, url);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") != -1) { //-1时不需验签
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);

                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));

                    if (flag) {
                        String status = respJSONObj.getString("Status");
                        if ("".equals(status) || status == null) {
                            retAts.retHashMap.put("RespCode", "-1");
                            retAts.retHashMap.put("RespInfo", "渠道返回Status非法");
                        } else {
                            //retAts.retHashMap.put("RefundStatus", "0".equals(status) ? "2" : "4");//不安全，还是再查一次
                            retAts.retHashMap.put("RespCode", "SUCCESS");
                            retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                            retAts.retHashMap.put("ReqNo", respJSONObj.getString("OutTradeNo"));
                            retAts.retHashMap.put("RefundNo", respJSONObj.getString("RefundNo"));
                            retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                            retAts.retHashMap.put("OutTradeId", respJSONObj.getString("FGTradeNo"));//保融订单号
                            retAts.retHashMap.put("FGRefundNo", respJSONObj.getString("FGRefundNo"));//保融退款单号
                            retAts.retHashMap.put("RefundChannel", respJSONObj.getString("RefundChannel"));//ORIGINAL-原路退款，默认
                            retAts.retHashMap.put("RefundFee", respJSONObj.getString("RefundFee"));//退款金额
                            if ("FGNATIVE02".equals(commandCode)) { //支付宝多返回4个，微信的尚未要求（返回为空），所以先过滤；暂时用不着，因为没返回退款状态，还会去查的
                                retAts.retHashMap.put("RefundChargeAmount", respJSONObj.getString("RefundChargeAmount"));//本次退款针对收款方的退收费金额
                                retAts.retHashMap.put("PresentRefundBuyerAmount", respJSONObj.getString("PresentRefundBuyerAmount"));//本次退款金额中买家退款金额
                                retAts.retHashMap.put("PresentRefundDiscountAmount", respJSONObj.getString("PresentRefundDiscountAmount"));//本次退款金额中平台优惠退款金额
                                retAts.retHashMap.put("PresentRefundMdiscountAmount", respJSONObj.getString("PresentRefundMdiscountAmount"));//本次退款金额中商家优惠退款金额
                            }
                        }

                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");//配合易企收的判断逻辑-1
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }

        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "0");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }


    private RetAtsOtherElse WechatScanPay(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String mchId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", mchId, "appId", "unifiedorder");
            if (actItem != null) {
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                String appId = actItem.appId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                String outTradeNo = p_reqElse.reqHashMap.get("OutTradeNo");
                String authCode = p_reqElse.reqHashMap.get("AuthCode");
                String totalFee = p_reqElse.reqHashMap.get("TotalFee");
                String body = p_reqElse.reqHashMap.get("Body");
                String goodsTag = p_reqElse.reqHashMap.get("GoodsTag");
                String organizationId = p_reqElse.reqHashMap.get("StoreId");
                String mchCreateIp = p_reqElse.reqHashMap.get("MchCreateIp");
                String attach = p_reqElse.reqHashMap.get("Attach");
                String timeStart = p_reqElse.reqHashMap.get("TimeStart");
                String timeExpire = p_reqElse.reqHashMap.get("TimeExpire");
                String nonceStr = get_nonce_str();

                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("AppId", appId);
                mapParams.put("AuthCode", authCode);
                mapParams.put("TotalFee", totalFee);
                mapParams.put("Body", body);
                mapParams.put("GoodsTag", goodsTag);
                mapParams.put("OrganizationId", organizationId);
                mapParams.put("MchCreateIp", mchCreateIp);
                mapParams.put("Attach", attach);
                mapParams.put("TimeStart", timeStart);
                mapParams.put("TimeExpire", timeExpire);
                mapParams.put("NonceStr", nonceStr);

                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey); //经过融汇webapi产品
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData); //签名
                mapParams.put("Signature", signature);
                String reqPostJson = getReqPostJson(mapParams); //获取待签名字段
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson); //加密
                String serverUrl = bankFront.getUrl("webapiWechatScanPayOrder");//微信条码支付请求地址

                String temStr = sendUnifiedToBank(reqSendData, serverUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);

                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") == 0) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("EnterpriseNum", respJSONObj.getString("EnterpriseNum"));
                        retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                        retAts.retHashMap.put("OutTradeId", respJSONObj.getString("FGTradeNo"));// 保融订单号
                        retAts.retHashMap.put("OutTradeNo", respJSONObj.getString("OutTradeNo"));
                        retAts.retHashMap.put("TotalFee", respJSONObj.getString("TotalFee"));
                        retAts.retHashMap.put("ReceiptFee", respJSONObj.getString("ReceiptFee"));
                        retAts.retHashMap.put("Transaction_id", respJSONObj.getString("Transaction_id")); //微信订单号
                        retAts.retHashMap.put("OpenId", respJSONObj.getString("OpenId")); // 用户微信在该公众号下的标识
                        retAts.retHashMap.put("AppId", appId);//返回到下单接口填充收单表
                        String timeEnd = respJSONObj.getString("TimeEnd");
                        if (!StringHelper.isNullOrEmpty(timeEnd)) {
                            try {
                                Date transDateStr = new SimpleDateFormat("yyyyMMddHHmmss").parse(timeEnd);
                                String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transDateStr);
                                retAts.retHashMap.put("timeEnd", dateStr);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        String tradeState = respJSONObj.getString("TradeState");
                        if ("SUCCESS".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "2");//支付成功
                            retAts.retHashMap.put("TransInfoCode", "S0000");//成功
                            retAts.retHashMap.put("TransInfo", "交易成功");
                        } else if ("PROCESSING".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "4");//支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "支付中");
                        } else if ("FAIL".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "3");//支付失败
                            retAts.retHashMap.put("TransInfoCode", "E8001");
                            retAts.retHashMap.put("TransInfo", "支付失败");
                        } else {
                            retAts.retHashMap.put("TransState", "4");//支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "未能识别" + tradeState);
                        }
                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");//与易企收原有逻辑相对，直接置为失败
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }

    /**
     * 智慧门店支付宝直联的条码支付
     *
     * @param p_reqElse
     * @return
     */
    private RetAtsOtherElse AliScanPay(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String mchId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", mchId, "appId", "unifiedorder");
            if (actItem != null) {

                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                String outTradeNo = p_reqElse.reqHashMap.get("OutTradeNo");
                String scene = p_reqElse.reqHashMap.get("Scene");
                String authCode = p_reqElse.reqHashMap.get("AuthCode");
                String subject = p_reqElse.reqHashMap.get("Subject");
                String totalFee = p_reqElse.reqHashMap.get("TotalFee");
                String discountableFee = p_reqElse.reqHashMap.get("DiscountableFee");
                String body = p_reqElse.reqHashMap.get("Body");
                String detail = p_reqElse.reqHashMap.get("GoodsDetail");
                String operatorId = p_reqElse.reqHashMap.get("OperatorId");
                String organizationId = p_reqElse.reqHashMap.get("StoreId");//接口字段调整：支付宝条码支付请求、退款请求门店编号字段改为组织机构号
                String terminalId = p_reqElse.reqHashMap.get("TerminalId");
                String notifyUrl = actItem.webAPINotifyUrl; //webapi使用一个共用的通知接口
                String timeStart = p_reqElse.reqHashMap.get("TimeStart");
                String timeExpire = p_reqElse.reqHashMap.get("TimeExpire");
                String callFlag = "00"; //缴费成功后除了正常结果通知是否还需要调外部系统，00：不回调，01：调用见费，默认为00，只做正常结果通知
                String nonceStr = get_nonce_str();


                JSONArray goodsDetailArray = new JSONArray();
                if (!"".equals(detail)) {
                    JSONArray jsonArray = JSONArray.parseArray(detail);
                    if (jsonArray != null && jsonArray.size() != 0) {
                        for (int i = 0; i < jsonArray.size(); i++) {
                            JSONObject goods_detail_i = new JSONObject();
                            goods_detail_i.put("GoodsId", jsonArray.getJSONObject(i).getString("goods_id"));
                            goods_detail_i.put("GoodsName", jsonArray.getJSONObject(i).getString("goods_name"));
                            goods_detail_i.put("Quantity", jsonArray.getJSONObject(i).getString("quantity"));
                            String price = jsonArray.getJSONObject(i).getString("price");
                            BigDecimal priceNum = new BigDecimal(price);
                            Long longPrice = priceNum.multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).longValue();
                            goods_detail_i.put("Price", longPrice);
                            goodsDetailArray.add(goods_detail_i);
                        }
                    }
                }
                String goodDetailStr = JSONObject.toJSONString(goodsDetailArray, SerializerFeature.DisableCircularReferenceDetect);
                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("Scene", scene);
                mapParams.put("AuthCode", authCode);
                mapParams.put("Subject", subject);
                mapParams.put("TotalFee", totalFee);
                mapParams.put("DiscountableFee", discountableFee);
                mapParams.put("Body", body);
                mapParams.put("GoodsDetail", goodDetailStr); //参与签名，但里边字段不需排序
                mapParams.put("OperatorId", operatorId);
                mapParams.put("OrganizationId", organizationId);
                mapParams.put("TerminalId", terminalId);
                mapParams.put("NotifyUrl", notifyUrl);
                mapParams.put("TimeStart", timeStart);
                mapParams.put("TimeExpire", timeExpire);
                mapParams.put("CallFlag", callFlag);
                mapParams.put("NonceStr", nonceStr);
                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey); //经过融汇webapi产品
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData); //签名
                mapParams.put("Signature", signature);
                String reqPostJson = getReqPostJson(mapParams); //获取待签名字段
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson); //加密
                String serverUrl = bankFront.getUrl("webapiAliScanPayOrder");//支付宝条码支付请求地址

                String temStr = sendUnifiedToBank(reqSendData, serverUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") == 0) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("EnterpriseNum", respJSONObj.getString("EnterpriseNum"));
                        retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                        retAts.retHashMap.put("OutTradeId", respJSONObj.getString("FGTradeNo"));// 保融订单号
                        retAts.retHashMap.put("OutTradeNo", respJSONObj.getString("OutTradeNo"));
                        retAts.retHashMap.put("TotalFee", respJSONObj.getString("TotalFee"));
                        retAts.retHashMap.put("ReceiptFee", respJSONObj.getString("ReceiptFee"));
                        retAts.retHashMap.put("Transaction_id", respJSONObj.getString("Transaction_id")); //支付宝订单号
                        retAts.retHashMap.put("OpenId", respJSONObj.getString("OpenId")); // 用户支付宝的账户名
                        retAts.retHashMap.put("ReceiptAmount", respJSONObj.getString("ReceiptAmount")); //商户实收金额
                        retAts.retHashMap.put("BuyerPayAmount", respJSONObj.getString("BuyerPayAmount")); //买家实付金额
                        retAts.retHashMap.put("MdiscountAmount", respJSONObj.getString("MdiscountAmount")); //商家优惠金额
                        retAts.retHashMap.put("DiscountAmount", respJSONObj.getString("DiscountAmount"));//平台优惠金额
                        String timeEnd = respJSONObj.getString("TimeEnd");
                        if (!StringHelper.isNullOrEmpty(timeEnd)) {
                            try {
                                Date transDateStr = new SimpleDateFormat("yyyyMMddHHmmss").parse(timeEnd);
                                String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transDateStr);
                                retAts.retHashMap.put("timeEnd", dateStr);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        String tradeState = respJSONObj.getString("TradeState");
                        if ("SUCCESS".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "2");//支付成功
                            retAts.retHashMap.put("TransInfoCode", "S0000");//成功
                            retAts.retHashMap.put("TransInfo", "交易成功");
                        } else if ("PROCESSING".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "4");//支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "支付中");
                        } else if ("FAIL".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "3");//支付失败
                            retAts.retHashMap.put("TransInfoCode", "E8001");
                            retAts.retHashMap.put("TransInfo", "支付失败");
                        } else {
                            retAts.retHashMap.put("TransState", "4");//支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "未能识别" + tradeState);
                        }
                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");//与易企收原有逻辑相对，直接置为失败
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }

        return retAts;
    }

    /**
     * webapi关闭订单接口
     *
     * @param p_reqElse
     * @return
     */
    private RetAtsOtherElse webAPICloseOrder(ReqOtherElse p_reqElse) {
        //未使用20190326
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String mchId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", mchId, "appId", "unifiedorder");
            if (actItem != null) {
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                String outTradeNo = p_reqElse.reqHashMap.get("OutTradeNo");
                String fGTradeNo = p_reqElse.reqHashMap.get("FGTradeNo");
                String nonceStr = get_nonce_str();
                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("FGTradeNo", fGTradeNo);
                mapParams.put("NonceStr", nonceStr);

                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey); //经过融汇webapi产品
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData); //签名
                mapParams.put("Signature", signature);
                String reqPostJson = getReqPostJson(mapParams); //获取待签名字段
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson); //加密
                String serverUrl = bankFront.getUrl("webapiCloseOrderSubmit");//webapi关单请求地址

                String temStr = sendUnifiedToBank(reqSendData, serverUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") == 0) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                    } else {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("REspInfo", "未找到相应账户、商户或公众号的配置！");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }

    /**
     * webapi撤销订单接口
     *
     * @param p_reqElse
     * @return
     */
    private RetAtsOtherElse webApiCancelOrder(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String mchId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", mchId, "appId", "unifiedorder");
            if (actItem != null) {
                //企业编号
                String enterpriseNum = actItem.inMerchantId;
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                String outTradeNo = p_reqElse.reqHashMap.get("OutTradeNo");
                String fGTradeNo = p_reqElse.reqHashMap.get("FGTradeNo");
                String nonceStr = get_nonce_str();
                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("FGTradeNo", fGTradeNo);
                mapParams.put("NonceStr", nonceStr);

                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey); //经过融汇webapi产品
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData); //签名
                mapParams.put("Signature", signature);
                String reqPostJson = getReqPostJson(mapParams); //获取待签名字段
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson); //加密
                String serverUrl = bankFront.getUrl("webapiCancelOrderSubmit");//webapi撤单请求地址

                String temStr = sendUnifiedToBank(reqSendData, serverUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") == 0) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                        retAts.retHashMap.put("RetryFlag", respJSONObj.getString("RetryFlag")); //撤销重试标，N表示不用再重试，Y表示需要重试，status 不为0时需要判断
                    } else {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                    retAts.retHashMap.put("RetryFlag", respJSONObj.getString("RetryFlag"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("REspInfo", "未找到相应账户、商户或公众号的配置！");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }


    /**
     * webapi聚合主扫
     *
     * @param p_reqElse
     * @return
     */
    private RetAtsOtherElse webApiAggregateMicroPay(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String mchId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", mchId, "appId", "unifiedorder");
            if (actItem != null) {
                String enterpriseNum = actItem.inMerchantId; //融汇分配的险企号
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "险企号EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("险企号EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }
                String outTradeNo = p_reqElse.reqHashMap.get("OutTradeNo");
                String appId = p_reqElse.reqHashMap.get("AppId"); //微信分配的微信公众号Id，可空
                String authCode = p_reqElse.reqHashMap.get("AuthCode");
                String totalFee = p_reqElse.reqHashMap.get("TotalFee");
                String body = p_reqElse.reqHashMap.get("Body");
                String organizationId = p_reqElse.reqHashMap.get("OrganizationId");
                String mchCreateIp = p_reqElse.reqHashMap.get("MchCreateIp");
                String attach = p_reqElse.reqHashMap.get("Attach");
                String timeStart = p_reqElse.reqHashMap.get("TimeStart");
                String timeExpire = p_reqElse.reqHashMap.get("TimeExpire");
                String nonceStr = get_nonce_str();

                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("AppId", appId);
                mapParams.put("AuthCode", authCode);
                mapParams.put("TotalFee", totalFee);
                mapParams.put("Body", body);
                mapParams.put("OrganizationId", organizationId);
                mapParams.put("MchCreateIp", mchCreateIp);
                mapParams.put("Attach", attach);
                mapParams.put("TimeStart", timeStart);
                mapParams.put("TimeExpire", timeExpire);
                mapParams.put("NonceStr", nonceStr);

                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey); //经过融汇webapi产品
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData); //签名
                mapParams.put("Signature", signature);
                String reqPostJson = getReqPostJson(mapParams); //获取待签名字段
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson); //加密

                String serveUrl = bankFront.getUrl("webApiAggregateMicroPayOrder");//webapi聚合主扫支付请求地址

                String temStr = sendUnifiedToBank(reqSendData, serveUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                //status为0是未知错误，无需验签
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") != -1) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String checkSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, checkSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("EnterpriseNum", respJSONObj.getString("EnterpriseNum"));
                        retAts.retHashMap.put("MchId", respJSONObj.getString("MchId"));
                        retAts.retHashMap.put("OutTradeId", respJSONObj.getString("FGTradeNo"));// 保融订单号
                        retAts.retHashMap.put("OutTradeNo", respJSONObj.getString("OutTradeNo"));
                        retAts.retHashMap.put("TotalFee", respJSONObj.getString("TotalFee"));
                        retAts.retHashMap.put("Transaction_id", respJSONObj.getString("Transaction_id")); //第三方订单号
                        retAts.retHashMap.put("OpenId", respJSONObj.getString("OpenId")); // 微信支付则为用户微信在该公众号下的标识，支付宝支付则为支付宝的用户id
                        String payType = respJSONObj.getString("PayType");
                        if ("1".equals(payType)) {
                            payType = "C1";
                        } else if ("2".equals(payType)) {
                            payType = "C2";
                        }
                        retAts.retHashMap.put("PayType", payType);//实际支付方式，1：支付宝，2：微信
                        String timeEnd = respJSONObj.getString("TimeEnd");
                        if (!StringHelper.isNullOrEmpty(timeEnd)) { //支付状态确认时间解析
                            try {
                                Date transDateStr = new SimpleDateFormat("yyyyMMddHHmmss").parse(timeEnd);
                                String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transDateStr);
                                retAts.retHashMap.put("TransTime", dateStr);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        String tradeState = respJSONObj.getString("TradeState");
                        if ("SUCCESS".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "2");//支付成功
                            retAts.retHashMap.put("TransInfoCode", "S0000");//成功
                            retAts.retHashMap.put("TransInfo", "交易成功");
                        } else if ("USERPAYING".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "4");//支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "支付中");
                        } else if ("FAIL".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "3");//支付失败
                            retAts.retHashMap.put("TransInfoCode", "E8001");
                            retAts.retHashMap.put("TransInfo", "支付失败");
                        } else {
                            retAts.retHashMap.put("TransState", "4");//支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "未能识别" + tradeState);
                        }
                    } else {
                        retAts.retHashMap.put("RespCode", "-1");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "0");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置，支付失败");
                retAts.retHashMap.put("TransState", "3");//支付失败
                retAts.retHashMap.put("TransInfoCode", "E8001");
                retAts.retHashMap.put("TransInfo", "未找到相应账户、商户或公众号的配置，支付失败");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }

    /**
     * webapi商户主扫支付结果查询
     *
     * @param p_reqElse
     * @return
     */
    private RetAtsOtherElse WebApiAggregateMicroPayQuery(ReqOtherElse p_reqElse) {
        RetAtsOtherElse retAts = new RetAtsOtherElse(p_reqElse.reqHeader);
        retAts.retHashMap = new HashMap<String, String>();
        try {
            String mchId = p_reqElse.reqHashMap.get("MchId");
            ActSetItem actItem = getBankConfig().getActSetItemByAny("", mchId, "appId", "unifiedorder");
            if (actItem != null) {
                String enterpriseNum = actItem.inMerchantId; //融汇分配的险企号
                if (StringHelper.isNullOrEmpty(enterpriseNum)) {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", "险企号EnterpriseNum为空，请配置inMerchantId映射");
                    WriteBankLogLn2("险企号EnterpriseNum为空，请配置inMerchantId映射");
                    return retAts;
                }

                String outTradeNo = p_reqElse.reqHashMap.get("ExchangeNo");
                String fGTradeNo = p_reqElse.reqHashMap.get("OutTradeId"); //兼容任务查询
                String nonceStr = get_nonce_str();

                HashMap<String, String> mapParams = new HashMap<String, String>();
                mapParams.put("EnterpriseNum", enterpriseNum);
                mapParams.put("MchId", mchId);
                mapParams.put("OutTradeNo", outTradeNo);
                mapParams.put("FGTradeNo", fGTradeNo);
                mapParams.put("NonceStr", nonceStr);

                // 签名
                String signData = getWebapiToSignData(mapParams, actItem.webAPISercretKey);
                WriteBankLogLn2("待签名数据:\r\n" + signData);
                String signature = signWebAPIFnGrd(actItem, signData);
                mapParams.put("Signature", signature);

                String reqPostJson = getReqPostJson(mapParams);
                boolean isNeed3Des = false;
                String reqSendData = getDataContent(isNeed3Des, actItem.inMerchantId, reqPostJson);

                String serveUrl = bankFront.getUrl("webApiAggregateMicroPayQuery");//webapi聚合主扫支付请求地址
                String temStr = sendUnifiedToBank(reqSendData, serveUrl);
                String sourceData = getSourceData(isNeed3Des, URLDecoder.decode(temStr, "UTF-8"));
                JSONObject respJSONObj = JSON.parseObject(sourceData);
                if (respJSONObj.containsKey("Status") && respJSONObj.getIntValue("Status") != -1) {
                    Map<String, Object> rmap = parseJSON2Map(sourceData);
                    String toSignData = getWebapiToSignDataFromMap(rmap, actItem.webAPISercretKey);
                    boolean flag = verifySign(actItem, toSignData, respJSONObj.getString("Signature"));
                    if (flag) {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                        retAts.retHashMap.put("OpenId", respJSONObj.getString("OpenId")); // 微信支付则为用户微信在该公众号下的标识，支付宝支付则为支付宝的用户id
                        retAts.retHashMap.put("OutTradeNo", respJSONObj.getString("OutTradeNo"));
                        retAts.retHashMap.put("OutTradeId", respJSONObj.getString("FGTradeNo"));// 保融订单号
                        retAts.retHashMap.put("TotalFee", respJSONObj.getString("TotalFee"));
                        retAts.retHashMap.put("Transaction_id", respJSONObj.getString("Transaction_id")); //第三方订单号
                        String timeEnd = respJSONObj.getString("TimeEnd");
                        if (!StringHelper.isNullOrEmpty(timeEnd)) { //支付状态确认时间解析
                            try {
                                Date transDateStr = new SimpleDateFormat("yyyyMMddHHmmss").parse(timeEnd);
                                String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(transDateStr);
                                retAts.retHashMap.put("TransTime", dateStr);
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                        }
                        String payType = respJSONObj.getString("PayType");
                        if ("1".equals(payType)) {
                            payType = "C1";
                        } else if ("2".equals(payType)) {
                            payType = "C2";
                        }
                        retAts.retHashMap.put("PayType", payType);//实际支付方式，1：支付宝，2：微信
                        String tradeState = respJSONObj.getString("TradeState");
                        if ("SUCCESS".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "2");//支付成功
                            retAts.retHashMap.put("TransInfoCode", "S0000");//成功
                            retAts.retHashMap.put("TransInfo", "交易成功");
                        } else if ("NOTPAY".equals(tradeState) || "USERPAYING".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "4");//未支付/支付中
                            retAts.retHashMap.put("TransInfoCode", "I4001");
                            retAts.retHashMap.put("TransInfo", "支付中");
                        } else if ("REFUND".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "2");//转入退款|| 已撤销
                            retAts.retHashMap.put("TransInfoCode", "S0000");//退票
                            retAts.retHashMap.put("TransInfo", "转入退款");
                        } else if ("PAYERROR".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "3");//支付失败(其他原因，如银行返回失败)||已关闭
                            retAts.retHashMap.put("TransInfoCode", "E8001");
                            retAts.retHashMap.put("TransInfo", "支付失败");
                        } else if ("REVERSE".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "12");//已撤销
                            retAts.retHashMap.put("TransInfoCode", "E8121");
                            retAts.retHashMap.put("TransInfo", "已撤销");
                        } else if ("CLOSED".equals(tradeState)) {
                            retAts.retHashMap.put("TransState", "11");//已关闭
                            retAts.retHashMap.put("TransInfoCode", "E8031");
                            retAts.retHashMap.put("TransInfo", "已关闭");
                        } else {
                            retAts.retHashMap.put("TransState", "4"); // TODO: 其他可知的状态怎么处理,先置为处理中
                            retAts.retHashMap.put("RespCode", "0");
                            retAts.retHashMap.put("TransInfo", "未知状态");
                            retAts.retHashMap.put("RespInfo", tradeState);
                        }
                    } else {
                        retAts.retHashMap.put("RespCode", "0");
                        retAts.retHashMap.put("RespInfo", "验证签名失败");
                    }
                } else {
                    retAts.retHashMap.put("RespCode", "-1");
                    retAts.retHashMap.put("RespInfo", respJSONObj.getString("ReturnMsg"));
                }
            } else {
                retAts.retHashMap.put("RespCode", "-1");
                retAts.retHashMap.put("RespInfo", "未找到相应账户、商户或公众号的配置");
            }
        } catch (Exception e) {
            retAts.retHashMap.put("RespCode", "-1");
            retAts.retHashMap.put("RespInfo", e.getMessage());
            WriteBankLogLn2("交互出错，原因如下:\r\n" + LogHelper.getStackTrace(e));
        }
        return retAts;
    }
}
